2016-07-15 33 views
0

In Rascal verhält sich das Pattern-Matching unterschiedlich mit und ohne Label (zumindest bei einem Besucher)? Ich schrieb die folgenden zwei Besucher, die den gleichen Syntaxbaum t besuchten. Der erste gibt "test" dreimal aus, was meines Erachtens korrekt ist, da es im Parse-Baum drei Vorkommen von "ParseCond" gibt (ich habe dies überprüft, indem ich den Baum gerendert und eine visuelle Inspektion durchgeführt habe). Der zweite Besucher druckt jedoch "Test" viel öfter.Unterschied in der Mustererkennung mit einem ohne Label in Besucher in Rascal

Ist dieses Verhalten hätte ich erwarten sollen? Oder könnte dieses Verhalten schlecht dokumentiert werden? Oder könnte es sogar ein Fehler sein?

Erste Besucher:

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

zweiter Besucher (man beachte den feinen Unterschied: Es ist ein Label "i" nach "IfCond"):

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

Der Code unten,

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

mit der folgenden grammer,

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

zeigt den Unterschied im Verhalten von Fällen mit und ohne Label, wenn sie auf eine Datei angewendet werden, die das folgende Code-Snippet enthält.

class A 
{ 
    int a = 0 
} 

countCmplFacts kehrt 1711, während countCmplFacts2 1 zurückgibt (die in diesem Fall meiner Meinung nach der richtige Wert ist).

+0

Das klingt wie ein Fehler, wir werden einen Blick darauf werfen und weitere Informationen posten, nachdem wir uns das angesehen haben. –

+0

könnten Sie ein vollständigeres Code-Beispiel veröffentlichen, das wir ausführen könnten? – jurgenv

+0

Ich habe meine Frage bearbeitet, um ein konkreteres Beispiel zu enthalten, @jurgenv. –

Antwort

2

Dieser Code tatsächlich passt jeden Wert:

case CmplFact: 

entspricht dies:

case x: 

oder

case value x: 

Anscheinend gibt es 1711 (verschachtelte) Werte in der gegeben Parse Baum!

Aber das Alternative Muster ist anders:

case CmplFact f 

Sie paßt und bindet jeden f, aber nur, wenn es vom Typ CmplFact, in diesem Fall nur einer.

+0

finde heraus, was "case x" stimmt, indem du alles druckst: 'println (x);': – jurgenv

+0

Wow, ich habe nie über die Möglichkeit nachgedacht, was ich als Typ bezeichnen wollte, wurde als Label interpretiert. Danke für Ihre Hilfe! Als Referenz: Der Rascal-Tutor gibt eindeutig an, dass Muster nur Typ- oder nicht typisierte Variablen sein können und nicht Typen, die keiner Variablen zugewiesen sind, während ich versuche, sie zu verwenden. Dies macht mich wundern –

+0

'obwohl: warum tut z. das folgende Beispiel aus dem Tutor arbeiten?'case leaf (int N)' Warum wird das nicht als Variable interpretiert, sondern als Typ (Konstruktor), während keine Variable dahinter steht? Ein Beispiel wie dieses lässt mich denken, dass ein "unmarkierter" Typ auch ein Muster sein könnte. (Entschuldigung für die versehentliche Trennung. Dieser Kommentar und der obige sollte einer gewesen sein) –