Странное "NoViableAltException" в грамматике дерева с мнимым токеном
Я не могу понять исключение "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(79@[])
error 100: syntax error: assign.types: NoViableAltException(0@[])
node from line 2482:10 no viable alternative at input '+'
error 100: syntax error: buildnfa: NoViableAltException(0@[])
error 100: syntax error: codegen: NoViableAltException(0@[])
error 100: syntax error: antlr.print: NoViableAltException(0@[])
error 100: syntax error: antlr.print: NoViableAltException(0@[])
Если я изменю грамматику дерева на:
keyword_controls_sub
: ^(MATCH_STATEMENT expression+)
;
Там нет ошибок компилятора, но я думаю, что это не правильно, так как в этом случае будет только один блок MATCH_STATEMENT.
Примечание: я использую ANTLR3 C Runtime.
Заранее спасибо.
1 ответ
Я удивлен, что корневой оператор может быть применен к блоку. На самом деле это имеет смысл только для одного токена, так как он отмечает этот токен как корень дерева. Кроме того, почему вы хотите дублировать виртуальный токен MATCH_STATEMENT несколько раз? Это совершенно излишне. Вы можете легко написать:
keyword_controls_sub:
MATCH_STATEMENT^ expression+
;
и получить все выражения как дочерние элементы под одним корневым узлом MATCH_STATEMENT.
И примечание: теперь есть цель C++ для ANTLR4. ANTLR3 довольно устарел, поэтому, возможно, вам стоит подумать об обновлении.