Olav Trauschke
Olav Trauschke

Reputation: 136

Difference in pattern matching with an without label in visitor in Rascal

In Rascal, why is it that pattern matching behaves differntly with and without label (at least in a visitor)? I wrote the following two visitors visiting the same parse tree t. The first one prints "test" three times, which is correct in my opinion as there are three occurrences of "ParseCond" in the parse tree (I checked this by rendering the tree and performing visual inspection). The second visitor, however, prints "test" many more times.

Is this behaviour I should have expected? Or might this behaviour be documented poorly? Or might it even be a bug?

First visitor:

visit(t) {
    case IfCond: print("test");
}

Second visitor (note the subtle difference: there is a label "i" after "IfCond"):

visit(t) {
    case IfCond i: print("test");
}

The below code,

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;
}

with the grammer below,

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          = "=";

shows the difference in behaviour of cases with and without label, when applied to a file containing the below code snippet.

class A
{
    int a = 0
}

countCmplFacts returns 1711, while countCmplFacts2 returns 1 (which is the correct value in this case in my opinion).

Upvotes: 0

Views: 141

Answers (1)

Jurgen Vinju
Jurgen Vinju

Reputation: 6696

This code actually matches any value:

 case CmplFact:

is equivalent to this:

 case x:

or

 case value x:

Apparently there are 1711 (nested) values in the given parse tree!

But the alternative pattern is different:

 case CmplFact f

It matches and binds any f, but only if it is of type CmplFact, in this case only one.

Upvotes: 2

Related Questions