在Rascal中,为什么带有和不带有标签的模式匹配行为都不同(至少在访问者中)?我写了以下两个访问者,访问同一棵分析树。第一个打印“测试”三遍,在我看来这是正确的,因为在分析树中出现了三处“ 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 = [\ \t\n\r];
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
(在这种情况下只有一个)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句