0

I can not understand a "NoViableAltException"exception when I compile my Tree grammar.

Here's a little piece of my grammar with the rule that gives me problems:

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

Which generates a tree like:

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

And the rule in my TreeGrammar that causes the exception:

keyword_controls_sub
    : ^(MATCH_STATEMENT expression)+
    ;

Specifically, the ANTLR compiler returns the following errors:

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@[])

If I change the tree grammar to:

keyword_controls_sub
: ^(MATCH_STATEMENT expression+)
;

There are no compiler errors, but I think that it is not correct, since in this case there would only be one MATCH_STATEMENT block.

Note: I'm using ANTLR3 C Runtime.

Thanks in advance.

Patxi
  • 43
  • 7

1 Answers1

0

I'm surprised the root operator can be applied to a block. It actually only makes sense for single token, as it marks this token as the root of a tree. Also, why do you want to duplicate the MATCH_STATEMENT virtual token multiple times? That's totally redundant. You could easily write:

keyword_controls_sub:
    MATCH_STATEMENT^ expression+
;

and get all expressions as children under a single MATCH_STATEMENT root node.

And a side note: there is now a C++ target for ANTLR4. ANTLR3 is quite outdated, so maybe you should consider upgrading.

Mike Lischke
  • 48,925
  • 16
  • 119
  • 181
  • There's two ways to write tree rewrites in ANTLR 3 - the `^(node1 ...)` syntax means the first node in the parentheses is the parent and all others are its children. It can even be nested like `^(level1 ^(level2 level3 level3) level2)`. Is that what you're wondering about? – Jiri Tousek Nov 21 '16 at 07:00
  • Yes, I know that, but the code for `keyword_controls_sub` has no rewrite operator, hence ^(...) is acting like a block. Not sure if that is even valid ANTLR syntax. – Mike Lischke Nov 21 '16 at 07:57
  • I've never used tree grammars, so I can only guess based on rewrite rules syntax. Maybe OP tried to use rewrite but got the syntax wrong and ANTLR interprets it as root operator? – Jiri Tousek Nov 21 '16 at 08:27
  • Thank you @MikeLischke!! Regarding your comment _"... get all expressions as children under a single MATCH_STATEMENT root node"_, is exactly what I have done and works correctly. But I still think the syntax `^(MATCH_STATEMENT expression+)` should be correct too. As for the new C++ runtime in ANTLR4, I am aware of it but it is very recent and I would rather wait a bit before doing the migration. – Patxi Nov 21 '16 at 09:02