op=(x|y) works as left-recur binary op now.

This commit is contained in:
Terence Parr 2012-03-30 13:00:31 -07:00
parent f166df7b94
commit 9fbe9b6e21
2 changed files with 18 additions and 19 deletions

View File

@ -128,17 +128,18 @@ outerAlternative returns [boolean isLeftRec]
{otherAlt((AltAST)$start, currentOuterAltNumber);} {otherAlt((AltAST)$start, currentOuterAltNumber);}
; ;
binary // (ALT (= a e) (= op (SET '*' '/')) (= b e) {}) (ALT INT {}) (ALT '(' (= x e) ')' {})
: ^( ALT recurse (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);} recurse ACTION? ) binaryMultipleOp
: ^( ALT recurse bops recurse ACTION? )
; ;
binaryMultipleOp bops: ^(ASSIGN ID bops)
: ^( ALT recurse | ^( BLOCK ( ^( ALT (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);} ) )+ )
( ^( BLOCK ( ^( ALT (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);} ) )+ )
| ^(SET (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);}) | ^(SET (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);})
) ;
recurse ACTION?
) binary
: ^( ALT recurse (op=token)+ {setTokenPrec($op.t, currentOuterAltNumber);} recurse ACTION? )
; ;
ternary ternary

View File

@ -229,21 +229,19 @@ public class TestLeftRecursion extends BaseTest {
} }
@Test public void testLabelsOnOpSubrule() throws Exception { @Test public void testLabelsOnOpSubrule() throws Exception {
// FAILS
String grammar = String grammar =
"grammar T;\n" + "grammar T;\n" +
"s : e {System.out.println($e.v);} ;\n" + "s @after {System.out.println($ctx.toStringTree(this));} : e ;\n" +
"e returns [int v, List<String> ignored]\n" + "e : a=e op=('*'|'/') b=e {}\n" +
" : a=e op=('*'|'/') b=e {$v = $a.v * $b.v;}\n" + " | INT {}\n" +
" | INT {$v = $INT.int;}\n" + " | '(' x=e ')' {}\n" +
" | '(' x=e ')' {$v = $x.v;}\n" +
" ;\n" + " ;\n" +
"INT : '0'..'9'+ ;\n" + "INT : '0'..'9'+ ;\n" +
"WS : (' '|'\\n') {skip();} ;\n"; "WS : (' '|'\\n') {skip();} ;\n";
String[] tests = { String[] tests = {
"4", "4", "4", "(s (e 4))",
"1*2/3", "7", "1*2/3", "(s (e (e (e 1) * (e 2)) / (e 3)))",
"(1/2)*3", "9", "(1/2)*3", "(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))",
}; };
runTests(grammar, tests, "s"); runTests(grammar, tests, "s");
} }