2016-11-18 10 views
0

Я не могу понять исключение «NoViableAltException» при компиляции моей грамматики Tree.Weird «NoViableAltException» в грамматике дерева с воображаемым токеном

Вот маленький кусочек моей грамматики с правилом, что дает мне проблемы:

keyword_controls_sub 
    : expression (MB_COMA expression)* -> ^(MATCH_STATEMENT expression)+ 
    ; 

, который генерирует дерево, как:

     +-----------------+ 
         |     | 
         |  ROOT  | 
         |     | 
         +-----------------+ 
           | 
           | 
      +-------------------------------------+ 
      |     |     | 
    +------------------+ +-----------------+ +-----------------+ 
    |     | |     | |     | 
    | MATCH_STATEMENT | | MATCH_STATEMENT | | MATCH_STATEMENT | 
    |     | |     | |     | 
    +------------------+ +-----------------+ +-----------------+ 
      |      |     | 
    +-------------------+ +-----------------+ +-----------------+ 
    |     | |     | |     | 
    | expression  | | expression | | expression | 
    |     | |     | |     | 
    +-------------------+ +-----------------+ +-----------------+ 

И правила в моем TreeGrammar, который вызывает исключение:

keyword_controls_sub 
    : ^(MATCH_STATEMENT expression)+ 
    ; 

В частности, компилятор ANTLR возвращает следующие ошибки:

error 100: syntax error: antlr: NoViableAltException([email protected][]) 
error 100: syntax error: assign.types: NoViableAltException([email protected][]) 
node from line 2482:10 no viable alternative at input '+' 
error 100: syntax error: buildnfa: NoViableAltException([email protected][]) 
error 100: syntax error: codegen: NoViableAltException([email protected][]) 
error 100: syntax error: antlr.print: NoViableAltException([email protected][]) 
error 100: syntax error: antlr.print: NoViableAltException([email protected][]) 

Если изменить грамматику дерево к:

keyword_controls_sub 
: ^(MATCH_STATEMENT expression+) 
; 

Там нет ошибок компилятора, но я думаю, что это не правильно, так как в этом случае будет только один MATCH_STATEMENT блок.

Примечание: Я использую ANTLR3 C Runtime.

Заранее спасибо.

ответ

0

Я удивлен, что оператор корня может быть применен к блоку. Это фактически имеет смысл только для одного токена, поскольку он отмечает этот токен как корень дерева. Кроме того, почему вы хотите дублировать виртуальный токен MATCH_STATEMENT несколько раз? Это абсолютно избыточно. Вы можете легко написать:

keyword_controls_sub: 
    MATCH_STATEMENT^ expression+ 
; 

и получить все выражения как дети под одним корневым узлом MATCH_STATEMENT.

И сторона примечание: теперь есть цель C++ для ANTLR4. ANTLR3 довольно устарел, поэтому, возможно, вам стоит подумать об обновлении.

+0

Существует два способа записи перезаписи дерева в ANTLR 3 - синтаксис '^ (node1 ...)' означает, что первым узлом в круглых скобках является родительский элемент, а все остальные - его дочерние элементы. Он может быть даже вложенным как '^ (level1^(level2 level3 level3) level2)'. Это то, о чем вам интересно? –

+0

Да, я это знаю, но код для 'keyword_controls_sub' не имеет оператора перезаписи, поэтому^(...) действует как блок. Не уверен, что это даже действительный синтаксис ANTLR. –

+0

Я никогда не использовал древовидные грамматики, поэтому я могу только предположить, основываясь на синтаксисе правил перезаписи. Может быть, OP попытался использовать переписать, но получил синтаксис неправильно, и ANTLR интерпретирует его как корневой оператор? –