diff --git a/tool/src/org/antlr/v4/parse/LeftRecursiveRuleWalker.g b/tool/src/org/antlr/v4/parse/LeftRecursiveRuleWalker.g index b02745302..679d7daa5 100644 --- a/tool/src/org/antlr/v4/parse/LeftRecursiveRuleWalker.g +++ b/tool/src/org/antlr/v4/parse/LeftRecursiveRuleWalker.g @@ -128,17 +128,18 @@ outerAlternative returns [boolean isLeftRec] {otherAlt((AltAST)$start, currentOuterAltNumber);} ; -binary - : ^( ALT recurse (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);} recurse ACTION? ) +// (ALT (= a e) (= op (SET '*' '/')) (= b e) {}) (ALT INT {}) (ALT '(' (= x e) ')' {}) +binaryMultipleOp + : ^( ALT recurse bops recurse ACTION? ) ; -binaryMultipleOp - : ^( ALT recurse - ( ^( BLOCK ( ^( ALT (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);} ) )+ ) - | ^(SET (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);}) - ) - recurse ACTION? - ) +bops: ^(ASSIGN ID bops) + | ^( BLOCK ( ^( ALT (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);} ) )+ ) + | ^(SET (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);}) + ; + +binary + : ^( ALT recurse (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);} recurse ACTION? ) ; ternary @@ -222,4 +223,4 @@ atom | ^(WILDCARD elementOptions) | WILDCARD | ^(DOT ID element) - ; \ No newline at end of file + ; diff --git a/tool/test/org/antlr/v4/test/TestLeftRecursion.java b/tool/test/org/antlr/v4/test/TestLeftRecursion.java index d37671bef..2eb813f66 100644 --- a/tool/test/org/antlr/v4/test/TestLeftRecursion.java +++ b/tool/test/org/antlr/v4/test/TestLeftRecursion.java @@ -229,21 +229,19 @@ public class TestLeftRecursion extends BaseTest { } @Test public void testLabelsOnOpSubrule() throws Exception { - // FAILS String grammar = "grammar T;\n" + - "s : e {System.out.println($e.v);} ;\n" + - "e returns [int v, List ignored]\n" + - " : a=e op=('*'|'/') b=e {$v = $a.v * $b.v;}\n" + - " | INT {$v = $INT.int;}\n" + - " | '(' x=e ')' {$v = $x.v;}\n" + + "s @after {System.out.println($ctx.toStringTree(this));} : e ;\n" + + "e : a=e op=('*'|'/') b=e {}\n" + + " | INT {}\n" + + " | '(' x=e ')' {}\n" + " ;\n" + "INT : '0'..'9'+ ;\n" + "WS : (' '|'\\n') {skip();} ;\n"; String[] tests = { - "4", "4", - "1*2/3", "7", - "(1/2)*3", "9", + "4", "(s (e 4))", + "1*2/3", "(s (e (e (e 1) * (e 2)) / (e 3)))", + "(1/2)*3", "(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))", }; runTests(grammar, tests, "s"); }