2016-07-15 5 views
0

В Rascal, почему это соответствие шаблонов ведет себя не так, как с ярлыком (и по крайней мере на посетителя)? Я написал следующие два посетителя, которые посещают одно и то же дерево разбора т. На мой взгляд, первый из них трижды печатает «тест», что, на мой взгляд, является правильным, поскольку в дереве синтаксического анализа есть три случая «ParseCond» (я проверил это, визуализировав дерево и выполнив визуальный контроль). Второй посетитель, однако, печатает «тест» еще много раз.Разница в сопоставлении с шаблоном без метки в посетителе в Rascal

Возможно ли такое поведение? Или это плохо документировано? Или это может быть ошибка?

Первый гость:

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

Второй посетитель (обратите внимание на тонкое различие: есть метка "я" после "IfCond"):

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 (что правильное значение в данном случае, на мой взгляд).

+0

Это звучит как ошибка, мы рассмотрим и опубликуем больше информации после того, как посмотрим на это. –

+0

Можете ли вы опубликовать более полный пример кода, который мы могли бы запустить? – jurgenv

+0

Я отредактировал мой вопрос, чтобы содержать более конкретный пример, @jurgenv. –

ответ

2

Этот код фактически соответствует любой значение:

case CmplFact: 

эквивалентно следующему:

case x: 

или

case value x: 

Видимо есть 1711 (вложенные) значения в данное дерево разбора!

Но альтернатива модель отличается:

case CmplFact f 

Это соответствует и связывает любой f, но только если он имеет тип CmplFact, в этом случае только один.

+0

выяснить, что 'case x' соответствует, распечатав все это:' println (x); ':-) – jurgenv

+0

Вау, я никогда не думал о возможности того, что я должен был соответствовать типу, был интерпретирован как метка. Спасибо за вашу помощь! Для справки: преподаватель Rascal четко заявляет, что шаблоны могут быть только типом или нетипизированными переменными, а не типами, которые не назначены переменной, как я пытался использовать. Это заставляет меня задаться вопросом –

+0

'хотя: почему именно. следующий пример из работы репетитора?'case leaf (int N)' Почему это не интерпретируется как переменная, а как тип (конструктор), в то время как после него нет переменной? Пример, подобный этому, заставляет меня думать, что тип «немеченого» тоже может быть шаблоном. (Извините за случайный раскол. Этот комментарий и один выше должны были быть такими) –