在流氓中,为什么模式匹配在有标签和没有标签的情况下表现得不同(至少在访问者中)?我写了以下两个访问同一个解析树t的访问者。第一个打印"test"三次,在我看来这是正确的,因为在解析树中有三次出现"ParseCond"(我通过渲染树并执行目视检查来检查这一点)。然而,第二个访问者打印"测试"的次数更多。
这种行为是我应该预料到的吗?或者这种行为可能记录得很差?或者它甚至可能是一个错误?
第一访客:
visit(t) {
case IfCond: print("test");
}
第二位访客(注意细微的区别:"IfCond"后面有一个标签"i"):
visit(t) {
case IfCond i: print("test");
}
下面的代码,
module t::Test
import ParseTree;
import t::SyntaxTest;
int countCmplFacts() {
Tree t = parse(#start[ClassDecl], |project://X++Analyzer/Test.xpp|);
int i = 0;
visit(t) {
case CmplFact: {
i += 1;
}
}
return i;
}
int countCmplFacts2() {
Tree t = parse(#start[ClassDecl], |project://X++Analyzer/Test.xpp|);
int i = 0;
visit(t) {
case CmplFact f: {
i += 1;
}
}
return i;
}
使用下面的格拉默,
module t::SyntaxTest
layout Layout = Whitespace* !>> Whitespace;
lexical Whitespace = [ tnr];
start syntax ClassDecl = ClassHeader LeftbrSym DclStmt RightbrSym;
syntax ClassHeader = Class StdId;
syntax DclStmt = Decl AsgClause;
syntax Decl = DeclType StdId;
syntax AsgClause = AsgSym CmplFact;
syntax CmplFact = IntSym;
lexical IntSym = [0-9]+;
lexical Class = ClassSym !>> [a-zA-Z0-9];
keyword ClassSym = "class";
lexical StdId = ([a-zA-Z][a-zA-Z0-9]*) !>> [a-zA-Z0-9];
lexical LeftbrSym = "{";
lexical RightbrSym = "}";
syntax DeclType = IntTypeSym !>> [a-zA-Z0-9];
keyword IntTypeSym = "int";
lexical AsgSym = "=";
显示了应用于包含以下代码片段的文件时,带标签和不带标签的情况的行为差异。
class A
{
int a = 0
}
countCmplFacts 返回 1711,而 countCmplFacts2 返回 1(在我看来,这是本例中的正确值)。
此代码实际上匹配任何值:
case CmplFact:
相当于这个:
case x:
或
case value x:
显然,给定的解析树中有 1711(嵌套)值!
但替代模式是不同的:
case CmplFact f
它匹配并绑定任何f
,但前提是它是CmplFact
类型,在这种情况下只有一个。