0

I'm learning ANTLR4 and I'm confused at one point. For a Java-like language, I'm trying to add rules for constructs like member chaining, something like that:

expr1.MethodCall(expr2).MethodCall(expr3);

I'm getting an error, saying that two of my rules are mutually left-recursive:

expression
    : literal
    | variableReference
    | LPAREN expression RPAREN
    | statementExpression
    | memberAccess
    ;

memberAccess: expression DOT (methodCall | fieldReference);

I thought I understood why the above rule combination is considered left-recursive: because memberAccess is a candidate of expression and memberAccess starts with an expression.

However, my understanding broke down when I saw (by looking at the Java example) that if I just move the contents of memberAccess to expression, I got no errors from ANTLR4 (even though it still doesn't parse what I want, seems to fall into a loop):

expression
    : literal
    | variableReference
    | LPAREN expression RPAREN
    | statementExpression
    | expression DOT (methodCall | fieldReference)
    ;
  1. Why is the first example left-recursive but the second isn't?
  2. And what do I have to do to actually parse the initial line?
Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104

2 Answers2

1

The second is left-recursive but not mutually left recursive. ANTLR4 can eliminate left-recursive rules with an inbuilt algorithm. It cannot eliminate mutually left recursive rules. There probably exists an algorithm, but this would hardly preserve actions and semantic predicates.

CoronA
  • 7,717
  • 2
  • 26
  • 53
  • I see. But what's the way to parse the example I've given? Everything I try seems to be mutually left-recursive, hang (infinite loop, maybe?) or parse incorrectly. – Theodoros Chatzigiannakis Apr 01 '15 at 16:23
  • Have you tried to reorder the alternatives with the second solution? What is the rule code of statementExpression. Is it clearly disjunct from the last line? Yet I cannot imagine which grammar lets the parser hang ... (ANTLR consumes at least one character per step, so unless an error occurs, is should reach the end and stop). – CoronA Apr 01 '15 at 16:29
  • I have tried reoreding and expanding as much as I could. I can't say for sure that I have tried all the permutations, but the tree of my test rig doesn't come up at all whenever I include an immediate left-recursive rule. So having anything like `expression DOT IDENTIFIER` as an alternative in `expression` doesn't generate anything. If I remove it, I get an output (but not what I want, of course). – Theodoros Chatzigiannakis Apr 03 '15 at 14:46
0

For some reason, ANTLRWorks 2 was not responding when my grammar had left-recursion, causing me to (erroneously) believe that my grammar was wrong.

Compiling and testing from commandline revealed that the version with immediate left-recursion did, in fact, compile and parse correctly.

(I'm leaving this here in case anyone else is confused by the behavior of the IDE.)

Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104