0

编译 Tree 语法时,我无法理解“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 运行时。

提前致谢。

4

1 回答 1

0

我很惊讶根运算符可以应用于块。它实际上只对单个令牌有意义,因为它将这个令牌标记为树的根。另外,为什么要多次复制 MATCH_STATEMENT 虚拟令牌?这完全是多余的。你可以很容易地写:

keyword_controls_sub:
    MATCH_STATEMENT^ expression+
;

并将所有表达式作为单个 MATCH_STATEMENT 根节点下的子节点。

附带说明:现在有一个针对 ANTLR4 的 C++ 目标。ANTLR3 已经过时了,所以也许你应该考虑升级。

于 2016-11-19T09:35:13.617 回答