forked from jasder/antlr
add {} in primary alt block to prevent ID|INT from becoming SET, which breaks code gen needs.
This commit is contained in:
parent
bd51907c5e
commit
9c1e58db7c
|
@ -1,6 +1,8 @@
|
|||
grammar T;
|
||||
s : f f EOF;
|
||||
f : | x;
|
||||
x : 'a' 'b';
|
||||
s : e ';' ;
|
||||
e : e '*' e
|
||||
| ID
|
||||
| INT
|
||||
;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') {skip();} ;
|
||||
|
|
|
@ -37,7 +37,7 @@ recRule(ruleName, precArgDef, argName, primaryAlts, opAlts, setResultAction,
|
|||
userRetvals, leftRecursiveRuleRefLabels) ::=
|
||||
<<
|
||||
<ruleName>[<precArgDef>]<if(userRetvals)> returns [<userRetvals>]<endif>
|
||||
: ( <primaryAlts:{alt | <alt.altText> }; separator="\n | ">
|
||||
: ( {} <primaryAlts:{alt | <alt.altText> }; separator="\n | ">
|
||||
)
|
||||
( <opAlts; separator="\n | ">
|
||||
)*
|
||||
|
|
|
@ -276,6 +276,59 @@ public class TestLeftRecursion extends BaseTest {
|
|||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbigLR() throws Exception {
|
||||
String grammar =
|
||||
"// START: g\n" +
|
||||
"grammar Expr;\n" +
|
||||
"// END: g\n" +
|
||||
"\n" +
|
||||
"// START:stat\n" +
|
||||
"prog: stat ;\n" +
|
||||
"\n" +
|
||||
"stat: expr NEWLINE -> printExpr\n" +
|
||||
" | ID '=' expr NEWLINE -> assign\n" +
|
||||
" | NEWLINE -> blank\n" +
|
||||
" ;\n" +
|
||||
"// END:stat\n" +
|
||||
"\n" +
|
||||
"// START:expr\n" +
|
||||
"expr: expr ('*'|'/') expr -> MulDiv\n" +
|
||||
" | expr ('+'|'-') expr -> AddSub\n" +
|
||||
" | INT -> int\n" +
|
||||
" | ID -> id\n" +
|
||||
" | '(' expr ')' -> parens\n" +
|
||||
" ;\n" +
|
||||
"// END:expr\n" +
|
||||
"\n" +
|
||||
"// show marginal cost of adding a clear/wipe command for memory\n" +
|
||||
"\n" +
|
||||
"// START:tokens\n" +
|
||||
"MUL : '*' ; // assigns token name to '*' used above in grammar\n" +
|
||||
"DIV : '/' ;\n" +
|
||||
"ADD : '+' ;\n" +
|
||||
"SUB : '-' ;\n" +
|
||||
"ID : [a-zA-Z]+ ; // match identifiers\n" +
|
||||
"INT : [0-9]+ ; // match integers\n" +
|
||||
"NEWLINE:'\\r'? '\\n' ; // return newlines to parser (is end-statement signal)\n" +
|
||||
"WS : [ \\t]+ -> skip ; // toss out whitespace\n" +
|
||||
"// END:tokens\n";
|
||||
String result = execParser("Expr.g4", grammar, "ExprParser", "ExprLexer", "prog", "1\n", true);
|
||||
assertNull(stderrDuringParse);
|
||||
|
||||
result = execParser("Expr.g4", grammar, "ExprParser", "ExprLexer", "prog", "a = 5\n", true);
|
||||
assertNull(stderrDuringParse);
|
||||
|
||||
result = execParser("Expr.g4", grammar, "ExprParser", "ExprLexer", "prog", "b = 6\n", true);
|
||||
assertNull(stderrDuringParse);
|
||||
|
||||
result = execParser("Expr.g4", grammar, "ExprParser", "ExprLexer", "prog", "a+b*2\n", true);
|
||||
assertNull(stderrDuringParse);
|
||||
|
||||
result = execParser("Expr.g4", grammar, "ExprParser", "ExprLexer", "prog", "(1+2)*3\n", true);
|
||||
assertNull(stderrDuringParse);
|
||||
}
|
||||
|
||||
public void runTests(String grammar, String[] tests, String startRule) {
|
||||
rawGenerateAndBuildRecognizer("T.g", grammar, "TParser", "TLexer");
|
||||
writeRecognizerAndCompile("TParser",
|
||||
|
|
Loading…
Reference in New Issue