Странное "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 довольно устарел, поэтому, возможно, вам стоит подумать об обновлении.

Другие вопросы по тегам