在流氓中与访客中没有标签的模式匹配的差异



在流氓中,为什么模式匹配在有标签和没有标签的情况下表现得不同(至少在访问者中)?我写了以下两个访问同一个解析树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类型,在这种情况下只有一个。

最新更新