Rascal 访问者中无标签模式匹配的差异
Difference in pattern matching with an without label in visitor in Rascal
在 Rascal 中,为什么模式匹配在有标签和没有标签的情况下表现不同(至少在访问者中)?我写了以下两个访问同一解析树 t 的访问者。第一个打印了 3 次 "test",我认为这是正确的,因为在解析树中出现了 3 次 "ParseCond"(我通过渲染树和执行目视检查来检查这一点)。然而,第二个访问者打印了 "test" 很多次。
这是我应该预料到的行为吗?或者这种行为可能没有得到很好的记录?或者它甚至可能是一个错误?
第一位访客:
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 returns 1711,而 countCmplFacts2 returns 1(我认为这是本例中的正确值)。
此代码实际匹配任何值:
case CmplFact:
相当于:
case x:
或
case value x:
显然在给定的解析树中有 1711 个(嵌套的)值!
但替代模式不同:
case CmplFact f
它匹配并绑定任何 f
,但前提是它是类型 CmplFact
,在本例中只有一个。
在 Rascal 中,为什么模式匹配在有标签和没有标签的情况下表现不同(至少在访问者中)?我写了以下两个访问同一解析树 t 的访问者。第一个打印了 3 次 "test",我认为这是正确的,因为在解析树中出现了 3 次 "ParseCond"(我通过渲染树和执行目视检查来检查这一点)。然而,第二个访问者打印了 "test" 很多次。
这是我应该预料到的行为吗?或者这种行为可能没有得到很好的记录?或者它甚至可能是一个错误?
第一位访客:
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 returns 1711,而 countCmplFacts2 returns 1(我认为这是本例中的正确值)。
此代码实际匹配任何值:
case CmplFact:
相当于:
case x:
或
case value x:
显然在给定的解析树中有 1711 个(嵌套的)值!
但替代模式不同:
case CmplFact f
它匹配并绑定任何 f
,但前提是它是类型 CmplFact
,在本例中只有一个。