validated LeftRecursion tests
This commit is contained in:
parent
31812721c8
commit
740c30d21d
|
@ -747,61 +747,61 @@ public class Generator {
|
|||
file.addParserTest(input, "SemPred", "T", "s", "x y z",
|
||||
"(s (a (a (a x) y) z))\n", null);
|
||||
file.addParserTests(input, "TernaryExpr", "T", "s",
|
||||
"a", "(s (e a) <EOF>)",
|
||||
"a+b", "(s (e (e a) + (e b)) <EOF>)",
|
||||
"a*b", "(s (e (e a) * (e b)) <EOF>)",
|
||||
"a?b:c", "(s (e (e a) ? (e b) : (e c)) <EOF>)",
|
||||
"a=b=c", "(s (e (e a) = (e (e b) = (e c))) <EOF>)",
|
||||
"a?b+c:d", "(s (e (e a) ? (e (e b) + (e c)) : (e d)) <EOF>)",
|
||||
"a?b=c:d", "(s (e (e a) ? (e (e b) = (e c)) : (e d)) <EOF>)",
|
||||
"a? b?c:d : e", "(s (e (e a) ? (e (e b) ? (e c) : (e d)) : (e e)) <EOF>)",
|
||||
"a?b: c?d:e", "(s (e (e a) ? (e b) : (e (e c) ? (e d) : (e e))) <EOF>)");
|
||||
"a", "(s (e a) <EOF>)\n",
|
||||
"a+b", "(s (e (e a) + (e b)) <EOF>)\n",
|
||||
"a*b", "(s (e (e a) * (e b)) <EOF>)\n",
|
||||
"a?b:c", "(s (e (e a) ? (e b) : (e c)) <EOF>)\n",
|
||||
"a=b=c", "(s (e (e a) = (e (e b) = (e c))) <EOF>)\n",
|
||||
"a?b+c:d", "(s (e (e a) ? (e (e b) + (e c)) : (e d)) <EOF>)\n",
|
||||
"a?b=c:d", "(s (e (e a) ? (e (e b) = (e c)) : (e d)) <EOF>)\n",
|
||||
"a? b?c:d : e", "(s (e (e a) ? (e (e b) ? (e c) : (e d)) : (e e)) <EOF>)\n",
|
||||
"a?b: c?d:e", "(s (e (e a) ? (e b) : (e (e c) ? (e d) : (e e))) <EOF>)\n");
|
||||
file.addParserTests(input, "Expressions", "T", "s",
|
||||
"a", "(s (e a) <EOF>)",
|
||||
"1", "(s (e 1) <EOF>)",
|
||||
"a-1", "(s (e (e a) - (e 1)) <EOF>)",
|
||||
"a.b", "(s (e (e a) . b) <EOF>)",
|
||||
"a.this", "(s (e (e a) . this) <EOF>)",
|
||||
"-a", "(s (e - (e a)) <EOF>)",
|
||||
"-a+b", "(s (e (e - (e a)) + (e b)) <EOF>)");
|
||||
"a", "(s (e a) <EOF>)\n",
|
||||
"1", "(s (e 1) <EOF>)\n",
|
||||
"a-1", "(s (e (e a) - (e 1)) <EOF>)\n",
|
||||
"a.b", "(s (e (e a) . b) <EOF>)\n",
|
||||
"a.this", "(s (e (e a) . this) <EOF>)\n",
|
||||
"-a", "(s (e - (e a)) <EOF>)\n",
|
||||
"-a+b", "(s (e (e - (e a)) + (e b)) <EOF>)\n");
|
||||
file.addParserTests(input, "JavaExpressions", "T", "s",
|
||||
"a|b&c", "(s (e (e a) | (e (e b) & (e c))) <EOF>)",
|
||||
"(a|b)&c", "(s (e (e ( (e (e a) | (e b)) )) & (e c)) <EOF>)",
|
||||
"a > b", "(s (e (e a) > (e b)) <EOF>)",
|
||||
"a >> b", "(s (e (e a) >> (e b)) <EOF>)",
|
||||
"a=b=c", "(s (e (e a) = (e (e b) = (e c))) <EOF>)",
|
||||
"a^b^c", "(s (e (e a) ^ (e (e b) ^ (e c))) <EOF>)",
|
||||
"(T)x", "(s (e ( (type T) ) (e x)) <EOF>)",
|
||||
"new A().b", "(s (e (e new (type A) ( )) . b) <EOF>)",
|
||||
"(T)t.f()", "(s (e (e ( (type T) ) (e (e t) . f)) ( )) <EOF>)",
|
||||
"a.f(x)==T.c", "(s (e (e (e (e a) . f) ( (expressionList (e x)) )) == (e (e T) . c)) <EOF>)",
|
||||
"a.f().g(x,1)", "(s (e (e (e (e (e a) . f) ( )) . g) ( (expressionList (e x) , (e 1)) )) <EOF>)",
|
||||
"new T[((n-1) * x) + 1]", "(s (e new (type T) [ (e (e ( (e (e ( (e (e n) - (e 1)) )) * (e x)) )) + (e 1)) ]) <EOF>)");
|
||||
"a|b&c", "(s (e (e a) | (e (e b) & (e c))) <EOF>)\n",
|
||||
"(a|b)&c", "(s (e (e ( (e (e a) | (e b)) )) & (e c)) <EOF>)\n",
|
||||
"a > b", "(s (e (e a) > (e b)) <EOF>)\n",
|
||||
"a >> b", "(s (e (e a) >> (e b)) <EOF>)\n",
|
||||
"a=b=c", "(s (e (e a) = (e (e b) = (e c))) <EOF>)\n",
|
||||
"a^b^c", "(s (e (e a) ^ (e (e b) ^ (e c))) <EOF>)\n",
|
||||
"(T)x", "(s (e ( (type T) ) (e x)) <EOF>)\n",
|
||||
"new A().b", "(s (e (e new (type A) ( )) . b) <EOF>)\n",
|
||||
"(T)t.f()", "(s (e (e ( (type T) ) (e (e t) . f)) ( )) <EOF>)\n",
|
||||
"a.f(x)==T.c", "(s (e (e (e (e a) . f) ( (expressionList (e x)) )) == (e (e T) . c)) <EOF>)\n",
|
||||
"a.f().g(x,1)", "(s (e (e (e (e (e a) . f) ( )) . g) ( (expressionList (e x) , (e 1)) )) <EOF>)\n",
|
||||
"new T[((n-1) * x) + 1]", "(s (e new (type T) [ (e (e ( (e (e ( (e (e n) - (e 1)) )) * (e x)) )) + (e 1)) ]) <EOF>)\n");
|
||||
file.addParserTests(input, "Declarations", "T", "s",
|
||||
"a", "(s (declarator a) <EOF>)",
|
||||
"*a", "(s (declarator * (declarator a)) <EOF>)",
|
||||
"**a", "(s (declarator * (declarator * (declarator a))) <EOF>)",
|
||||
"a[3]", "(s (declarator (declarator a) [ (e 3) ]) <EOF>)",
|
||||
"b[]", "(s (declarator (declarator b) [ ]) <EOF>)",
|
||||
"(a)", "(s (declarator ( (declarator a) )) <EOF>)",
|
||||
"a[]()", "(s (declarator (declarator (declarator a) [ ]) ( )) <EOF>)",
|
||||
"a[][]", "(s (declarator (declarator (declarator a) [ ]) [ ]) <EOF>)",
|
||||
"*a[]", "(s (declarator * (declarator (declarator a) [ ])) <EOF>)",
|
||||
"(*a)[]", "(s (declarator (declarator ( (declarator * (declarator a)) )) [ ]) <EOF>)");
|
||||
"a", "(s (declarator a) <EOF>)\n",
|
||||
"*a", "(s (declarator * (declarator a)) <EOF>)\n",
|
||||
"**a", "(s (declarator * (declarator * (declarator a))) <EOF>)\n",
|
||||
"a[3]", "(s (declarator (declarator a) [ (e 3) ]) <EOF>)\n",
|
||||
"b[]", "(s (declarator (declarator b) [ ]) <EOF>)\n",
|
||||
"(a)", "(s (declarator ( (declarator a) )) <EOF>)\n",
|
||||
"a[]()", "(s (declarator (declarator (declarator a) [ ]) ( )) <EOF>)\n",
|
||||
"a[][]", "(s (declarator (declarator (declarator a) [ ]) [ ]) <EOF>)\n",
|
||||
"*a[]", "(s (declarator * (declarator (declarator a) [ ])) <EOF>)\n",
|
||||
"(*a)[]", "(s (declarator (declarator ( (declarator * (declarator a)) )) [ ]) <EOF>)\n");
|
||||
file.addParserTests(input, "ReturnValueAndActions", "T", "s",
|
||||
"4", "4",
|
||||
"1+2", "3",
|
||||
"1+2*3", "7",
|
||||
"(1+2)*3", "9");
|
||||
"4", "4\n",
|
||||
"1+2", "3\n",
|
||||
"1+2*3", "7\n",
|
||||
"(1+2)*3", "9\n");
|
||||
file.addParserTests(input, "LabelsOnOpSubrule", "T", "s",
|
||||
"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)))");
|
||||
"4", "(s (e 4))\n",
|
||||
"1*2/3", "(s (e (e (e 1) * (e 2)) / (e 3)))\n",
|
||||
"(1/2)*3", "(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))\n");
|
||||
file.addParserTests(input, "ReturnValueAndActionsAndLabels", "T", "s",
|
||||
"4", "4",
|
||||
"1+2", "3",
|
||||
"1+2*3", "7",
|
||||
"i++*3", "12");
|
||||
"4", "4\n",
|
||||
"1+2", "3\n",
|
||||
"1+2*3", "7\n",
|
||||
"i++*3", "12\n");
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#433 "Not all context accessor
|
||||
* methods are generated when an alternative rule label is used for multiple
|
||||
|
@ -809,14 +809,14 @@ public class Generator {
|
|||
* https://github.com/antlr/antlr4/issues/433
|
||||
*/
|
||||
file.addParserTests(input, "MultipleAlternativesWithCommonLabel", "T", "s",
|
||||
"4", "4",
|
||||
"1+2", "3",
|
||||
"1+2*3", "7",
|
||||
"i++*3", "12");
|
||||
"4", "4\n",
|
||||
"1+2", "3\n",
|
||||
"1+2*3", "7\n",
|
||||
"i++*3", "12\n");
|
||||
file.addParserTests(input, "PrefixOpWithActionAndLabel", "T", "s",
|
||||
"a", "a",
|
||||
"a+b", "(a+b)",
|
||||
"a=b+c", "((a=b)+c)");
|
||||
"a", "a\n",
|
||||
"a+b", "(a+b)\n",
|
||||
"a=b+c", "((a=b)+c)\n");
|
||||
file.addParserTests(input, "AmbigLR", "Expr", "prog",
|
||||
"1\n", "",
|
||||
"a = 5\n", "",
|
||||
|
@ -839,6 +839,69 @@ public class Generator {
|
|||
file.addParserTest(input, "PrecedenceFilterConsidersContext", "T", "prog",
|
||||
"aa",
|
||||
"(prog (statement (letterA a)) (statement (letterA a)) <EOF>)\n", null);
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#625 "Duplicate action breaks
|
||||
* operator precedence"
|
||||
* https://github.com/antlr/antlr4/issues/625
|
||||
*/
|
||||
file.addParserTests(input, "MultipleActions", "T", "s",
|
||||
"4", "(s (e 4))\n",
|
||||
"1*2/3", "(s (e (e (e 1) * (e 2)) / (e 3)))\n",
|
||||
"(1/2)*3", "(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))\n");
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#625 "Duplicate action breaks
|
||||
* operator precedence"
|
||||
* https://github.com/antlr/antlr4/issues/625
|
||||
*/
|
||||
file.addParserTests(input, "MultipleActionsPredicatesOptions", "T", "s",
|
||||
"4", "(s (e 4))\n",
|
||||
"1*2/3", "(s (e (e (e 1) * (e 2)) / (e 3)))\n",
|
||||
"(1/2)*3", "(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))\n");
|
||||
file.addParserTest(input, "SemPredFailOption", "T", "s",
|
||||
"x y z",
|
||||
"(s (a (a x) y z))\n",
|
||||
"line 1:4 rule a custom message\n");
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#542 "First alternative cannot
|
||||
* be right-associative".
|
||||
* https://github.com/antlr/antlr4/issues/542
|
||||
*/
|
||||
file.addParserTests(input, "TernaryExprExplicitAssociativity", "T", "s",
|
||||
"a", "(s (e a) <EOF>)\n",
|
||||
"a+b", "(s (e (e a) + (e b)) <EOF>)\n",
|
||||
"a*b", "(s (e (e a) * (e b)) <EOF>)\n",
|
||||
"a?b:c", "(s (e (e a) ? (e b) : (e c)) <EOF>)\n",
|
||||
"a=b=c", "(s (e (e a) = (e (e b) = (e c))) <EOF>)\n",
|
||||
"a?b+c:d", "(s (e (e a) ? (e (e b) + (e c)) : (e d)) <EOF>)\n",
|
||||
"a?b=c:d", "(s (e (e a) ? (e (e b) = (e c)) : (e d)) <EOF>)\n",
|
||||
"a? b?c:d : e", "(s (e (e a) ? (e (e b) ? (e c) : (e d)) : (e e)) <EOF>)\n",
|
||||
"a?b: c?d:e", "(s (e (e a) ? (e b) : (e (e c) ? (e d) : (e e))) <EOF>)\n");
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#677 "labels not working in
|
||||
* grammar file".
|
||||
* https://github.com/antlr/antlr4/issues/677
|
||||
*
|
||||
* <p>This test treats {@code ,} and {@code >>} as part of a single compound
|
||||
* operator (similar to a ternary operator).</p>
|
||||
*/
|
||||
file.addParserTests(input, "ReturnValueAndActionsList1", "T", "s",
|
||||
"a*b", "(s (expr (expr a) * (expr b)) <EOF>)\n",
|
||||
"a,c>>x", "(s (expr (expr a) , (expr c) >> (expr x)) <EOF>)\n",
|
||||
"x", "(s (expr x) <EOF>)\n",
|
||||
"a*b,c,x*y>>r", "(s (expr (expr (expr a) * (expr b)) , (expr c) , (expr (expr x) * (expr y)) >> (expr r)) <EOF>)\n");
|
||||
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#677 "labels not working in
|
||||
* grammar file".
|
||||
* https://github.com/antlr/antlr4/issues/677
|
||||
*
|
||||
* <p>This test treats the {@code ,} and {@code >>} operators separately.</p>
|
||||
*/
|
||||
file.addParserTests(input, "ReturnValueAndActionsList2", "T", "s",
|
||||
"a*b", "(s (expr (expr a) * (expr b)) <EOF>)\n",
|
||||
"a,c>>x", "(s (expr (expr (expr a) , (expr c)) >> (expr x)) <EOF>)\n",
|
||||
"x", "(s (expr x) <EOF>)\n",
|
||||
"a*b,c,x*y>>r", "(s (expr (expr (expr (expr (expr a) * (expr b)) , (expr c)) , (expr (expr x) * (expr y))) >> (expr r)) <EOF>)\n");
|
||||
return file;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
grammar <grammarName>;
|
||||
s @after {<ToStringTree("$ctx"):writeln()>} : e ;
|
||||
e : a=e op=('*'|'/') b=e {}{}
|
||||
| INT {}{}
|
||||
| '(' x=e ')' {}{}
|
||||
;
|
||||
INT : '0'..'9'+ ;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -0,0 +1,9 @@
|
|||
grammar <grammarName>;
|
||||
s @after {<ToStringTree("$ctx"):writeln()>} : e ;
|
||||
e : a=e op=('*'|'/') b=e {}{true}?
|
||||
| a=e op=('+'|'-') b=e {}\<p=3>{true}?\<fail='Message'>
|
||||
| INT {}{}
|
||||
| '(' x=e ')' {}{}
|
||||
;
|
||||
INT : '0'..'9'+ ;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,13 +1,13 @@
|
|||
grammar <grammarName>;
|
||||
s : e {<writeln("$e.v")>};
|
||||
e returns [int v]
|
||||
: e '*' e {$v = $ctx.e(0).v * $ctx.e(1).v;} # binary
|
||||
| e '+' e {$v = $ctx.e(0).v + $ctx.e(1).v;} # binary
|
||||
: e '*' e {$v = <Cast("BinaryContext","$ctx")>.e(0).v * <Cast("BinaryContext","$ctx")>.e(1).v;} # binary
|
||||
| e '+' e {$v = <Cast("BinaryContext","$ctx")>.e(0).v + <Cast("BinaryContext","$ctx")>.e(1).v;} # binary
|
||||
| INT {$v = $INT.int;} # anInt
|
||||
| '(' e ')' {$v = $e.v;} # parens
|
||||
| left=e INC {<assert("$ctx.INC() !== null")>;$v = $left.v + 1;} # unary
|
||||
| left=e DEC {<assert("$ctx.DEC() !== null")>;$v = $left.v - 1;} # unary
|
||||
| ID {$v = 3} # anID
|
||||
| left=e INC {<Cast("UnaryContext","$ctx"):Concat(".INC() != null"):Assert()>$v = $left.v + 1;} # unary
|
||||
| left=e DEC {<Cast("UnaryContext","$ctx"):Concat(".DEC() != null"):Assert()>$v = $left.v - 1;} # unary
|
||||
| ID {<AssignLocal("$v","3")>} # anID
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+ ;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
grammar <grammarName>;
|
||||
s : e {<writeln("$e.result")>} ;
|
||||
e returns [String result]
|
||||
: ID '=' e1=e {$result = \"(\" + $ID.text + \"=\" + $e1.result + \")\";}
|
||||
: ID '=' e1=e {$result = "(" + $ID.text + "=" + $e1.result + ")";}
|
||||
| ID {$result = $ID.text;}
|
||||
| e1=e '+' e2=e {$result = \"(\" + $e1.result + \"+\" + $e2.result + \")\";}
|
||||
| e1=e '+' e2=e {$result = "(" + $e1.result + "+" + $e2.result + ")";}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+ ;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
grammar <grammarName>;
|
||||
s : e {<writeln("$e.v")>};
|
||||
e returns [int v, list ignored]
|
||||
e returns [int v, <StringList()> ignored]
|
||||
: a=e '*' b=e {$v = $a.v * $b.v;}
|
||||
| a=e '+' b=e {$v = $a.v + $b.v;}
|
||||
| INT {$v = $INT.int;}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
grammar <grammarName>;
|
||||
s @after {<ToStringTree("$ctx"):writeln()>} : expr EOF;
|
||||
expr:
|
||||
a=expr '*' a=expr #Factor
|
||||
| b+=expr (',' b+=expr)* '>>' c=expr #Send
|
||||
| ID #JustId //semantic check on modifiers
|
||||
;
|
||||
|
||||
ID : ('a'..'z'|'A'..'Z'|'_')
|
||||
('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
|
||||
;
|
||||
|
||||
WS : [ \t\n]+ -> skip ;
|
|
@ -0,0 +1,12 @@
|
|||
grammar <grammarName>;
|
||||
s @after {<ToStringTree("$ctx"):writeln()>} : expr EOF;
|
||||
expr:
|
||||
a=expr '*' a=expr #Factor
|
||||
| b+=expr ',' b+=expr #Comma
|
||||
| b+=expr '>>' c=expr #Send
|
||||
| ID #JustId //semantic check on modifiers
|
||||
;
|
||||
ID : ('a'..'z'|'A'..'Z'|'_')
|
||||
('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
|
||||
;
|
||||
WS : [ \t\n]+ -> skip ;
|
|
@ -0,0 +1,7 @@
|
|||
grammar <grammarName>;
|
||||
s @after {<ToStringTree("$ctx"):writeln()>} : a ;
|
||||
a : a ID {false}?\<fail='custom message'>
|
||||
| ID
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -0,0 +1,10 @@
|
|||
grammar <grammarName>;
|
||||
s @after {<ToStringTree("$ctx"):writeln()>} : e EOF; // must indicate EOF can follow or 'a\<EOF>' won't match
|
||||
e :\<assoc=right> e '*' e
|
||||
|\<assoc=right> e '+' e
|
||||
|\<assoc=right> e '?' e ':' e
|
||||
|\<assoc=right> e '=' e
|
||||
| ID
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -46,4 +46,4 @@ DATE : '\'' DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT (
|
|||
SQ_STRING : '\'' ('\'\'' | ~'\'')* '\'';
|
||||
DQ_STRING : '\"' ('\\\"' | ~'\"')* '\"';
|
||||
WS : [ \t\n\r]+ -> skip ;
|
||||
COMMENTS : ('/*' .*? '*/' | '//' ~'\n'* '\n' ) -> skip;\n";
|
||||
COMMENTS : ('/*' .*? '*/' | '//' ~'\n'* '\n' ) -> skip;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
grammar <grammarName>;
|
||||
ifStatement
|
||||
@after {
|
||||
<DeclareLocal("items = $ctx.elseIfStatement()")>
|
||||
<DeclareLocal("items","$ctx.elseIfStatement()")>
|
||||
}
|
||||
: 'if' expression
|
||||
( ( 'then'
|
||||
|
|
|
@ -99,9 +99,15 @@ writeln(s) ::= <<System.out.println(<s>);>>
|
|||
|
||||
write(s) ::= <<System.out.print(<s>);>>
|
||||
|
||||
assert(s) ::= <<console.assert(<s>);>>
|
||||
Assert(s) ::= <<assert(<s>);>>
|
||||
|
||||
DeclareLocal(s) ::= "Object <s>;"
|
||||
Cast(t,v) ::= "((<t>)<v>)"
|
||||
|
||||
Concat(a,b) ::= "<a><b>"
|
||||
|
||||
DeclareLocal(s,v) ::= "Object <s> = <v>;"
|
||||
|
||||
AssignLocal(s,v) ::= "<s> = <v>;"
|
||||
|
||||
InitMember(n,v) ::= <%this.<n> = <v>;%>
|
||||
|
||||
|
@ -123,6 +129,8 @@ DumpDFA() ::= "this.dumpDFA();"
|
|||
|
||||
Pass() ::= ""
|
||||
|
||||
StringList() ::= "List\<String>"
|
||||
|
||||
BuildParseTrees() ::= "this.buildParseTrees = true;"
|
||||
|
||||
BailErrorStrategy() ::= <%setErrorHandler(new BailErrorStrategy());%>
|
||||
|
|
|
@ -99,63 +99,63 @@ public class TestLeftRecursion extends BaseTest {
|
|||
@Test
|
||||
public void testTernaryExpr_1() throws Exception {
|
||||
String found = testTernaryExpr("a");
|
||||
assertEquals("(s (e a) <EOF>)", found);
|
||||
assertEquals("(s (e a) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExpr_2() throws Exception {
|
||||
String found = testTernaryExpr("a+b");
|
||||
assertEquals("(s (e (e a) + (e b)) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) + (e b)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExpr_3() throws Exception {
|
||||
String found = testTernaryExpr("a*b");
|
||||
assertEquals("(s (e (e a) * (e b)) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) * (e b)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExpr_4() throws Exception {
|
||||
String found = testTernaryExpr("a?b:c");
|
||||
assertEquals("(s (e (e a) ? (e b) : (e c)) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) ? (e b) : (e c)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExpr_5() throws Exception {
|
||||
String found = testTernaryExpr("a=b=c");
|
||||
assertEquals("(s (e (e a) = (e (e b) = (e c))) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) = (e (e b) = (e c))) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExpr_6() throws Exception {
|
||||
String found = testTernaryExpr("a?b+c:d");
|
||||
assertEquals("(s (e (e a) ? (e (e b) + (e c)) : (e d)) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) ? (e (e b) + (e c)) : (e d)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExpr_7() throws Exception {
|
||||
String found = testTernaryExpr("a?b=c:d");
|
||||
assertEquals("(s (e (e a) ? (e (e b) = (e c)) : (e d)) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) ? (e (e b) = (e c)) : (e d)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExpr_8() throws Exception {
|
||||
String found = testTernaryExpr("a? b?c:d : e");
|
||||
assertEquals("(s (e (e a) ? (e (e b) ? (e c) : (e d)) : (e e)) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) ? (e (e b) ? (e c) : (e d)) : (e e)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExpr_9() throws Exception {
|
||||
String found = testTernaryExpr("a?b: c?d:e");
|
||||
assertEquals("(s (e (e a) ? (e b) : (e (e c) ? (e d) : (e e))) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) ? (e b) : (e (e c) ? (e d) : (e e))) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
|
@ -179,49 +179,49 @@ public class TestLeftRecursion extends BaseTest {
|
|||
@Test
|
||||
public void testExpressions_1() throws Exception {
|
||||
String found = testExpressions("a");
|
||||
assertEquals("(s (e a) <EOF>)", found);
|
||||
assertEquals("(s (e a) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpressions_2() throws Exception {
|
||||
String found = testExpressions("1");
|
||||
assertEquals("(s (e 1) <EOF>)", found);
|
||||
assertEquals("(s (e 1) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpressions_3() throws Exception {
|
||||
String found = testExpressions("a-1");
|
||||
assertEquals("(s (e (e a) - (e 1)) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) - (e 1)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpressions_4() throws Exception {
|
||||
String found = testExpressions("a.b");
|
||||
assertEquals("(s (e (e a) . b) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) . b) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpressions_5() throws Exception {
|
||||
String found = testExpressions("a.this");
|
||||
assertEquals("(s (e (e a) . this) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) . this) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpressions_6() throws Exception {
|
||||
String found = testExpressions("-a");
|
||||
assertEquals("(s (e - (e a)) <EOF>)", found);
|
||||
assertEquals("(s (e - (e a)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpressions_7() throws Exception {
|
||||
String found = testExpressions("-a+b");
|
||||
assertEquals("(s (e (e - (e a)) + (e b)) <EOF>)", found);
|
||||
assertEquals("(s (e (e - (e a)) + (e b)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
|
@ -288,84 +288,84 @@ public class TestLeftRecursion extends BaseTest {
|
|||
@Test
|
||||
public void testJavaExpressions_1() throws Exception {
|
||||
String found = testJavaExpressions("a|b&c");
|
||||
assertEquals("(s (e (e a) | (e (e b) & (e c))) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) | (e (e b) & (e c))) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaExpressions_2() throws Exception {
|
||||
String found = testJavaExpressions("(a|b)&c");
|
||||
assertEquals("(s (e (e ( (e (e a) | (e b)) )) & (e c)) <EOF>)", found);
|
||||
assertEquals("(s (e (e ( (e (e a) | (e b)) )) & (e c)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaExpressions_3() throws Exception {
|
||||
String found = testJavaExpressions("a > b");
|
||||
assertEquals("(s (e (e a) > (e b)) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) > (e b)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaExpressions_4() throws Exception {
|
||||
String found = testJavaExpressions("a >> b");
|
||||
assertEquals("(s (e (e a) >> (e b)) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) >> (e b)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaExpressions_5() throws Exception {
|
||||
String found = testJavaExpressions("a=b=c");
|
||||
assertEquals("(s (e (e a) = (e (e b) = (e c))) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) = (e (e b) = (e c))) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaExpressions_6() throws Exception {
|
||||
String found = testJavaExpressions("a^b^c");
|
||||
assertEquals("(s (e (e a) ^ (e (e b) ^ (e c))) <EOF>)", found);
|
||||
assertEquals("(s (e (e a) ^ (e (e b) ^ (e c))) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaExpressions_7() throws Exception {
|
||||
String found = testJavaExpressions("(T)x");
|
||||
assertEquals("(s (e ( (type T) ) (e x)) <EOF>)", found);
|
||||
assertEquals("(s (e ( (type T) ) (e x)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaExpressions_8() throws Exception {
|
||||
String found = testJavaExpressions("new A().b");
|
||||
assertEquals("(s (e (e new (type A) ( )) . b) <EOF>)", found);
|
||||
assertEquals("(s (e (e new (type A) ( )) . b) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaExpressions_9() throws Exception {
|
||||
String found = testJavaExpressions("(T)t.f()");
|
||||
assertEquals("(s (e (e ( (type T) ) (e (e t) . f)) ( )) <EOF>)", found);
|
||||
assertEquals("(s (e (e ( (type T) ) (e (e t) . f)) ( )) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaExpressions_10() throws Exception {
|
||||
String found = testJavaExpressions("a.f(x)==T.c");
|
||||
assertEquals("(s (e (e (e (e a) . f) ( (expressionList (e x)) )) == (e (e T) . c)) <EOF>)", found);
|
||||
assertEquals("(s (e (e (e (e a) . f) ( (expressionList (e x)) )) == (e (e T) . c)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaExpressions_11() throws Exception {
|
||||
String found = testJavaExpressions("a.f().g(x,1)");
|
||||
assertEquals("(s (e (e (e (e (e a) . f) ( )) . g) ( (expressionList (e x) , (e 1)) )) <EOF>)", found);
|
||||
assertEquals("(s (e (e (e (e (e a) . f) ( )) . g) ( (expressionList (e x) , (e 1)) )) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJavaExpressions_12() throws Exception {
|
||||
String found = testJavaExpressions("new T[((n-1) * x) + 1]");
|
||||
assertEquals("(s (e new (type T) [ (e (e ( (e (e ( (e (e n) - (e 1)) )) * (e x)) )) + (e 1)) ]) <EOF>)", found);
|
||||
assertEquals("(s (e new (type T) [ (e (e ( (e (e ( (e (e n) - (e 1)) )) * (e x)) )) + (e 1)) ]) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
|
@ -390,77 +390,77 @@ public class TestLeftRecursion extends BaseTest {
|
|||
@Test
|
||||
public void testDeclarations_1() throws Exception {
|
||||
String found = testDeclarations("a");
|
||||
assertEquals("(s (declarator a) <EOF>)", found);
|
||||
assertEquals("(s (declarator a) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclarations_2() throws Exception {
|
||||
String found = testDeclarations("*a");
|
||||
assertEquals("(s (declarator * (declarator a)) <EOF>)", found);
|
||||
assertEquals("(s (declarator * (declarator a)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclarations_3() throws Exception {
|
||||
String found = testDeclarations("**a");
|
||||
assertEquals("(s (declarator * (declarator * (declarator a))) <EOF>)", found);
|
||||
assertEquals("(s (declarator * (declarator * (declarator a))) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclarations_4() throws Exception {
|
||||
String found = testDeclarations("a[3]");
|
||||
assertEquals("(s (declarator (declarator a) [ (e 3) ]) <EOF>)", found);
|
||||
assertEquals("(s (declarator (declarator a) [ (e 3) ]) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclarations_5() throws Exception {
|
||||
String found = testDeclarations("b[]");
|
||||
assertEquals("(s (declarator (declarator b) [ ]) <EOF>)", found);
|
||||
assertEquals("(s (declarator (declarator b) [ ]) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclarations_6() throws Exception {
|
||||
String found = testDeclarations("(a)");
|
||||
assertEquals("(s (declarator ( (declarator a) )) <EOF>)", found);
|
||||
assertEquals("(s (declarator ( (declarator a) )) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclarations_7() throws Exception {
|
||||
String found = testDeclarations("a[]()");
|
||||
assertEquals("(s (declarator (declarator (declarator a) [ ]) ( )) <EOF>)", found);
|
||||
assertEquals("(s (declarator (declarator (declarator a) [ ]) ( )) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclarations_8() throws Exception {
|
||||
String found = testDeclarations("a[][]");
|
||||
assertEquals("(s (declarator (declarator (declarator a) [ ]) [ ]) <EOF>)", found);
|
||||
assertEquals("(s (declarator (declarator (declarator a) [ ]) [ ]) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclarations_9() throws Exception {
|
||||
String found = testDeclarations("*a[]");
|
||||
assertEquals("(s (declarator * (declarator (declarator a) [ ])) <EOF>)", found);
|
||||
assertEquals("(s (declarator * (declarator (declarator a) [ ])) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclarations_10() throws Exception {
|
||||
String found = testDeclarations("(*a)[]");
|
||||
assertEquals("(s (declarator (declarator ( (declarator * (declarator a)) )) [ ]) <EOF>)", found);
|
||||
assertEquals("(s (declarator (declarator ( (declarator * (declarator a)) )) [ ]) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
String testReturnValueAndActions(String input) throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : e {System.out.println($e.v);}; \n" +
|
||||
"e returns [int v, list ignored]\n" +
|
||||
"e returns [int v, List<String> ignored]\n" +
|
||||
" : a=e '*' b=e {$v = $a.v * $b.v;}\n" +
|
||||
" | a=e '+' b=e {$v = $a.v + $b.v;}\n" +
|
||||
" | INT {$v = $INT.int;}\n" +
|
||||
|
@ -474,28 +474,28 @@ public class TestLeftRecursion extends BaseTest {
|
|||
@Test
|
||||
public void testReturnValueAndActions_1() throws Exception {
|
||||
String found = testReturnValueAndActions("4");
|
||||
assertEquals("4", found);
|
||||
assertEquals("4\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActions_2() throws Exception {
|
||||
String found = testReturnValueAndActions("1+2");
|
||||
assertEquals("3", found);
|
||||
assertEquals("3\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActions_3() throws Exception {
|
||||
String found = testReturnValueAndActions("1+2*3");
|
||||
assertEquals("7", found);
|
||||
assertEquals("7\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActions_4() throws Exception {
|
||||
String found = testReturnValueAndActions("(1+2)*3");
|
||||
assertEquals("9", found);
|
||||
assertEquals("9\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
|
@ -514,21 +514,21 @@ public class TestLeftRecursion extends BaseTest {
|
|||
@Test
|
||||
public void testLabelsOnOpSubrule_1() throws Exception {
|
||||
String found = testLabelsOnOpSubrule("4");
|
||||
assertEquals("(s (e 4))", found);
|
||||
assertEquals("(s (e 4))\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLabelsOnOpSubrule_2() throws Exception {
|
||||
String found = testLabelsOnOpSubrule("1*2/3");
|
||||
assertEquals("(s (e (e (e 1) * (e 2)) / (e 3)))", found);
|
||||
assertEquals("(s (e (e (e 1) * (e 2)) / (e 3)))\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLabelsOnOpSubrule_3() throws Exception {
|
||||
String found = testLabelsOnOpSubrule("(1/2)*3");
|
||||
assertEquals("(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))", found);
|
||||
assertEquals("(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
|
@ -553,28 +553,28 @@ public class TestLeftRecursion extends BaseTest {
|
|||
@Test
|
||||
public void testReturnValueAndActionsAndLabels_1() throws Exception {
|
||||
String found = testReturnValueAndActionsAndLabels("4");
|
||||
assertEquals("4", found);
|
||||
assertEquals("4\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActionsAndLabels_2() throws Exception {
|
||||
String found = testReturnValueAndActionsAndLabels("1+2");
|
||||
assertEquals("3", found);
|
||||
assertEquals("3\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActionsAndLabels_3() throws Exception {
|
||||
String found = testReturnValueAndActionsAndLabels("1+2*3");
|
||||
assertEquals("7", found);
|
||||
assertEquals("7\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActionsAndLabels_4() throws Exception {
|
||||
String found = testReturnValueAndActionsAndLabels("i++*3");
|
||||
assertEquals("12", found);
|
||||
assertEquals("12\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
|
@ -582,13 +582,13 @@ public class TestLeftRecursion extends BaseTest {
|
|||
String grammar = "grammar T;\n" +
|
||||
"s : e {System.out.println($e.v);}; \n" +
|
||||
"e returns [int v]\n" +
|
||||
" : e '*' e {$v = $ctx.e(0).v * $ctx.e(1).v;} # binary\n" +
|
||||
" | e '+' e {$v = $ctx.e(0).v + $ctx.e(1).v;} # binary\n" +
|
||||
" : e '*' e {$v = ((BinaryContext)$ctx).e(0).v * ((BinaryContext)$ctx).e(1).v;} # binary\n" +
|
||||
" | e '+' e {$v = ((BinaryContext)$ctx).e(0).v + ((BinaryContext)$ctx).e(1).v;} # binary\n" +
|
||||
" | INT {$v = $INT.int;} # anInt\n" +
|
||||
" | '(' e ')' {$v = $e.v;} # parens\n" +
|
||||
" | left=e INC {console.assert($ctx.INC() !== null);;$v = $left.v + 1;} # unary\n" +
|
||||
" | left=e DEC {console.assert($ctx.DEC() !== null);;$v = $left.v - 1;} # unary\n" +
|
||||
" | ID {$v = 3} # anID\n" +
|
||||
" | left=e INC {assert(((UnaryContext)$ctx).INC() != null);$v = $left.v + 1;} # unary\n" +
|
||||
" | left=e DEC {assert(((UnaryContext)$ctx).DEC() != null);$v = $left.v - 1;} # unary\n" +
|
||||
" | ID {$v = 3;} # anID\n" +
|
||||
" ; \n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+ ;\n" +
|
||||
|
@ -601,28 +601,28 @@ public class TestLeftRecursion extends BaseTest {
|
|||
@Test
|
||||
public void testMultipleAlternativesWithCommonLabel_1() throws Exception {
|
||||
String found = testMultipleAlternativesWithCommonLabel("4");
|
||||
assertEquals("4", found);
|
||||
assertEquals("4\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleAlternativesWithCommonLabel_2() throws Exception {
|
||||
String found = testMultipleAlternativesWithCommonLabel("1+2");
|
||||
assertEquals("3", found);
|
||||
assertEquals("3\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleAlternativesWithCommonLabel_3() throws Exception {
|
||||
String found = testMultipleAlternativesWithCommonLabel("1+2*3");
|
||||
assertEquals("7", found);
|
||||
assertEquals("7\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleAlternativesWithCommonLabel_4() throws Exception {
|
||||
String found = testMultipleAlternativesWithCommonLabel("i++*3");
|
||||
assertEquals("12", found);
|
||||
assertEquals("12\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
|
@ -630,9 +630,9 @@ public class TestLeftRecursion extends BaseTest {
|
|||
String grammar = "grammar T;\n" +
|
||||
"s : e {System.out.println($e.result);} ;\n" +
|
||||
"e returns [String result]\n" +
|
||||
" : ID '=' e1=e {$result = \\\"(\\\" + $ID.text + \\\"=\\\" + $e1.result + \\\")\\\";}\n" +
|
||||
" : ID '=' e1=e {$result = \"(\" + $ID.text + \"=\" + $e1.result + \")\";}\n" +
|
||||
" | ID {$result = $ID.text;}\n" +
|
||||
" | e1=e '+' e2=e {$result = \\\"(\\\" + $e1.result + \\\"+\\\" + $e2.result + \\\")\\\";}\n" +
|
||||
" | e1=e '+' e2=e {$result = \"(\" + $e1.result + \"+\" + $e2.result + \")\";}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+ ;\n" +
|
||||
|
@ -643,21 +643,21 @@ public class TestLeftRecursion extends BaseTest {
|
|||
@Test
|
||||
public void testPrefixOpWithActionAndLabel_1() throws Exception {
|
||||
String found = testPrefixOpWithActionAndLabel("a");
|
||||
assertEquals("a", found);
|
||||
assertEquals("a\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrefixOpWithActionAndLabel_2() throws Exception {
|
||||
String found = testPrefixOpWithActionAndLabel("a+b");
|
||||
assertEquals("(a+b)", found);
|
||||
assertEquals("(a+b)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrefixOpWithActionAndLabel_3() throws Exception {
|
||||
String found = testPrefixOpWithActionAndLabel("a=b+c");
|
||||
assertEquals("((a=b)+c)", found);
|
||||
assertEquals("((a=b)+c)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
|
@ -770,7 +770,7 @@ public class TestLeftRecursion extends BaseTest {
|
|||
"SQ_STRING : '\\'' ('\\'\\'' | ~'\\'')* '\\'';\n" +
|
||||
"DQ_STRING : '\\\"' ('\\\\\"' | ~'\\\"')* '\\\"';\n" +
|
||||
"WS : [ \\t\\n\\r]+ -> skip ;\n" +
|
||||
"COMMENTS : ('/*' .*? '*/' | '//' ~'\\n'* '\\n' ) -> skip;\\n\";";
|
||||
"COMMENTS : ('/*' .*? '*/' | '//' ~'\\n'* '\\n' ) -> skip;";
|
||||
return execParser("Expr.g4", grammar, "ExprParser", "ExprLexer", "prog", input, false);
|
||||
}
|
||||
|
||||
|
@ -801,5 +801,252 @@ public class TestLeftRecursion extends BaseTest {
|
|||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
String testMultipleActions(String input) throws Exception {
|
||||
String grammar = "grammar T;\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 ;";
|
||||
return execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleActions_1() throws Exception {
|
||||
String found = testMultipleActions("4");
|
||||
assertEquals("(s (e 4))\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleActions_2() throws Exception {
|
||||
String found = testMultipleActions("1*2/3");
|
||||
assertEquals("(s (e (e (e 1) * (e 2)) / (e 3)))\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleActions_3() throws Exception {
|
||||
String found = testMultipleActions("(1/2)*3");
|
||||
assertEquals("(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
String testMultipleActionsPredicatesOptions(String input) throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : e ;\n" +
|
||||
"e : a=e op=('*'|'/') b=e {}{true}?\n" +
|
||||
" | a=e op=('+'|'-') b=e {}<p=3>{true}?<fail='Message'>\n" +
|
||||
" | INT {}{}\n" +
|
||||
" | '(' x=e ')' {}{}\n" +
|
||||
" ;\n" +
|
||||
"INT : '0'..'9'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
return execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleActionsPredicatesOptions_1() throws Exception {
|
||||
String found = testMultipleActionsPredicatesOptions("4");
|
||||
assertEquals("(s (e 4))\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleActionsPredicatesOptions_2() throws Exception {
|
||||
String found = testMultipleActionsPredicatesOptions("1*2/3");
|
||||
assertEquals("(s (e (e (e 1) * (e 2)) / (e 3)))\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleActionsPredicatesOptions_3() throws Exception {
|
||||
String found = testMultipleActionsPredicatesOptions("(1/2)*3");
|
||||
assertEquals("(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSemPredFailOption() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : a ;\n" +
|
||||
"a : a ID {false}?<fail='custom message'>\n" +
|
||||
" | ID\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "x y z", false);
|
||||
assertEquals("(s (a (a x) y z))\n", found);
|
||||
assertEquals("line 1:4 rule a custom message\n", this.stderrDuringParse);
|
||||
}
|
||||
|
||||
String testTernaryExprExplicitAssociativity(String input) throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : e EOF; // must indicate EOF can follow or 'a<EOF>' won't match\n" +
|
||||
"e :<assoc=right> e '*' e\n" +
|
||||
" |<assoc=right> e '+' e\n" +
|
||||
" |<assoc=right> e '?' e ':' e\n" +
|
||||
" |<assoc=right> e '=' e\n" +
|
||||
" | ID\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
return execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExprExplicitAssociativity_1() throws Exception {
|
||||
String found = testTernaryExprExplicitAssociativity("a");
|
||||
assertEquals("(s (e a) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExprExplicitAssociativity_2() throws Exception {
|
||||
String found = testTernaryExprExplicitAssociativity("a+b");
|
||||
assertEquals("(s (e (e a) + (e b)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExprExplicitAssociativity_3() throws Exception {
|
||||
String found = testTernaryExprExplicitAssociativity("a*b");
|
||||
assertEquals("(s (e (e a) * (e b)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExprExplicitAssociativity_4() throws Exception {
|
||||
String found = testTernaryExprExplicitAssociativity("a?b:c");
|
||||
assertEquals("(s (e (e a) ? (e b) : (e c)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExprExplicitAssociativity_5() throws Exception {
|
||||
String found = testTernaryExprExplicitAssociativity("a=b=c");
|
||||
assertEquals("(s (e (e a) = (e (e b) = (e c))) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExprExplicitAssociativity_6() throws Exception {
|
||||
String found = testTernaryExprExplicitAssociativity("a?b+c:d");
|
||||
assertEquals("(s (e (e a) ? (e (e b) + (e c)) : (e d)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExprExplicitAssociativity_7() throws Exception {
|
||||
String found = testTernaryExprExplicitAssociativity("a?b=c:d");
|
||||
assertEquals("(s (e (e a) ? (e (e b) = (e c)) : (e d)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExprExplicitAssociativity_8() throws Exception {
|
||||
String found = testTernaryExprExplicitAssociativity("a? b?c:d : e");
|
||||
assertEquals("(s (e (e a) ? (e (e b) ? (e c) : (e d)) : (e e)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernaryExprExplicitAssociativity_9() throws Exception {
|
||||
String found = testTernaryExprExplicitAssociativity("a?b: c?d:e");
|
||||
assertEquals("(s (e (e a) ? (e b) : (e (e c) ? (e d) : (e e))) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
String testReturnValueAndActionsList1(String input) throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : expr EOF;\n" +
|
||||
"expr:\n" +
|
||||
" a=expr '*' a=expr #Factor\n" +
|
||||
" | b+=expr (',' b+=expr)* '>>' c=expr #Send\n" +
|
||||
" | ID #JustId //semantic check on modifiers\n" +
|
||||
";\n" +
|
||||
"\n" +
|
||||
"ID : ('a'..'z'|'A'..'Z'|'_')\n" +
|
||||
" ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*\n" +
|
||||
";\n" +
|
||||
"\n" +
|
||||
"WS : [ \\t\\n]+ -> skip ;";
|
||||
return execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActionsList1_1() throws Exception {
|
||||
String found = testReturnValueAndActionsList1("a*b");
|
||||
assertEquals("(s (expr (expr a) * (expr b)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActionsList1_2() throws Exception {
|
||||
String found = testReturnValueAndActionsList1("a,c>>x");
|
||||
assertEquals("(s (expr (expr a) , (expr c) >> (expr x)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActionsList1_3() throws Exception {
|
||||
String found = testReturnValueAndActionsList1("x");
|
||||
assertEquals("(s (expr x) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActionsList1_4() throws Exception {
|
||||
String found = testReturnValueAndActionsList1("a*b,c,x*y>>r");
|
||||
assertEquals("(s (expr (expr (expr a) * (expr b)) , (expr c) , (expr (expr x) * (expr y)) >> (expr r)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
String testReturnValueAndActionsList2(String input) throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : expr EOF;\n" +
|
||||
"expr:\n" +
|
||||
" a=expr '*' a=expr #Factor\n" +
|
||||
" | b+=expr ',' b+=expr #Comma\n" +
|
||||
" | b+=expr '>>' c=expr #Send\n" +
|
||||
" | ID #JustId //semantic check on modifiers\n" +
|
||||
" ;\n" +
|
||||
"ID : ('a'..'z'|'A'..'Z'|'_')\n" +
|
||||
" ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*\n" +
|
||||
";\n" +
|
||||
"WS : [ \\t\\n]+ -> skip ;";
|
||||
return execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActionsList2_1() throws Exception {
|
||||
String found = testReturnValueAndActionsList2("a*b");
|
||||
assertEquals("(s (expr (expr a) * (expr b)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActionsList2_2() throws Exception {
|
||||
String found = testReturnValueAndActionsList2("a,c>>x");
|
||||
assertEquals("(s (expr (expr (expr a) , (expr c)) >> (expr x)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActionsList2_3() throws Exception {
|
||||
String found = testReturnValueAndActionsList2("x");
|
||||
assertEquals("(s (expr x) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnValueAndActionsList2_4() throws Exception {
|
||||
String found = testReturnValueAndActionsList2("a*b,c,x*y>>r");
|
||||
assertEquals("(s (expr (expr (expr (expr (expr a) * (expr b)) , (expr c)) , (expr (expr x) * (expr y))) >> (expr r)) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -33,520 +33,10 @@ package org.antlr.v4.test.tool;
|
|||
import org.antlr.v4.tool.ErrorType;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/** */
|
||||
public class TestLeftRecursion extends BaseTest {
|
||||
protected boolean debug = false;
|
||||
|
||||
@Test public void testSimple() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : a ;\n" +
|
||||
"a : a ID\n" +
|
||||
" | ID" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer",
|
||||
"s", "x", debug);
|
||||
String expecting = "(s (a x))\n";
|
||||
assertEquals(expecting, found);
|
||||
|
||||
found = execParser("T.g4", grammar, "TParser", "TLexer",
|
||||
"s", "x y", debug);
|
||||
expecting = "(s (a (a x) y))\n";
|
||||
assertEquals(expecting, found);
|
||||
|
||||
found = execParser("T.g4", grammar, "TParser", "TLexer",
|
||||
"s", "x y z", debug);
|
||||
expecting = "(s (a (a (a x) y) z))\n";
|
||||
assertEquals(expecting, found);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a regression test for "Support direct calls to left-recursive
|
||||
* rules".
|
||||
* https://github.com/antlr/antlr4/issues/161
|
||||
*/
|
||||
@Test public void testDirectCallToLeftRecursiveRule() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"a @after {System.out.println($ctx.toStringTree(this));} : a ID\n" +
|
||||
" | ID" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer",
|
||||
"a", "x", debug);
|
||||
String expecting = "(a x)\n";
|
||||
assertEquals(expecting, found);
|
||||
|
||||
found = execParser("T.g4", grammar, "TParser", "TLexer",
|
||||
"a", "x y", debug);
|
||||
expecting = "(a (a x) y)\n";
|
||||
assertEquals(expecting, found);
|
||||
|
||||
found = execParser("T.g4", grammar, "TParser", "TLexer",
|
||||
"a", "x y z", debug);
|
||||
expecting = "(a (a (a x) y) z)\n";
|
||||
assertEquals(expecting, found);
|
||||
}
|
||||
|
||||
@Test public void testSemPred() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : a ;\n" +
|
||||
"a : a {true}? ID\n" +
|
||||
" | ID" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer",
|
||||
"s", "x y z", debug);
|
||||
String expecting = "(s (a (a (a x) y) z))\n";
|
||||
assertEquals(expecting, found);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSemPredFailOption() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : a ;\n" +
|
||||
"a : a ID {false}?<fail='custom message'>\n" +
|
||||
" | ID" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer",
|
||||
"s", "x y z", debug);
|
||||
String expecting = "(s (a (a x) y z))\n";
|
||||
assertEquals(expecting, found);
|
||||
assertEquals("line 1:4 rule a custom message\n", stderrDuringParse);
|
||||
}
|
||||
|
||||
@Test public void testTernaryExpr() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : e EOF ;\n" + // must indicate EOF can follow or 'a<EOF>' won't match
|
||||
"e : e '*' e" +
|
||||
" | e '+' e" +
|
||||
" |<assoc=right> e '?' e ':' e" +
|
||||
" |<assoc=right> e '=' e" +
|
||||
" | ID" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String[] tests = {
|
||||
"a", "(s (e a) <EOF>)",
|
||||
"a+b", "(s (e (e a) + (e b)) <EOF>)",
|
||||
"a*b", "(s (e (e a) * (e b)) <EOF>)",
|
||||
"a?b:c", "(s (e (e a) ? (e b) : (e c)) <EOF>)",
|
||||
"a=b=c", "(s (e (e a) = (e (e b) = (e c))) <EOF>)",
|
||||
"a?b+c:d", "(s (e (e a) ? (e (e b) + (e c)) : (e d)) <EOF>)",
|
||||
"a?b=c:d", "(s (e (e a) ? (e (e b) = (e c)) : (e d)) <EOF>)",
|
||||
"a? b?c:d : e", "(s (e (e a) ? (e (e b) ? (e c) : (e d)) : (e e)) <EOF>)",
|
||||
"a?b: c?d:e", "(s (e (e a) ? (e b) : (e (e c) ? (e d) : (e e))) <EOF>)",
|
||||
};
|
||||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#542 "First alternative cannot
|
||||
* be right-associative".
|
||||
* https://github.com/antlr/antlr4/issues/542
|
||||
*/
|
||||
@Test public void testTernaryExprExplicitAssociativity() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : e EOF ;\n" + // must indicate EOF can follow or 'a<EOF>' won't match
|
||||
"e :<assoc=right> e '*' e" +
|
||||
" |<assoc=right> e '+' e" +
|
||||
" |<assoc=right> e '?' e ':' e" +
|
||||
" |<assoc=right> e '=' e" +
|
||||
" | ID" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String[] tests = {
|
||||
"a", "(s (e a) <EOF>)",
|
||||
"a+b", "(s (e (e a) + (e b)) <EOF>)",
|
||||
"a*b", "(s (e (e a) * (e b)) <EOF>)",
|
||||
"a?b:c", "(s (e (e a) ? (e b) : (e c)) <EOF>)",
|
||||
"a=b=c", "(s (e (e a) = (e (e b) = (e c))) <EOF>)",
|
||||
"a?b+c:d", "(s (e (e a) ? (e (e b) + (e c)) : (e d)) <EOF>)",
|
||||
"a?b=c:d", "(s (e (e a) ? (e (e b) = (e c)) : (e d)) <EOF>)",
|
||||
"a? b?c:d : e", "(s (e (e a) ? (e (e b) ? (e c) : (e d)) : (e e)) <EOF>)",
|
||||
"a?b: c?d:e", "(s (e (e a) ? (e b) : (e (e c) ? (e d) : (e e))) <EOF>)",
|
||||
};
|
||||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
@Test public void testExpressions() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : e EOF ;\n" + // must indicate EOF can follow
|
||||
"e : e '.' ID\n" +
|
||||
" | e '.' 'this'\n" +
|
||||
" | '-' e\n" +
|
||||
" | e '*' e\n" +
|
||||
" | e ('+'|'-') e\n" +
|
||||
" | INT\n" +
|
||||
" | ID\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String[] tests = {
|
||||
"a", "(s (e a) <EOF>)",
|
||||
"1", "(s (e 1) <EOF>)",
|
||||
"a-1", "(s (e (e a) - (e 1)) <EOF>)",
|
||||
"a.b", "(s (e (e a) . b) <EOF>)",
|
||||
"a.this", "(s (e (e a) . this) <EOF>)",
|
||||
"-a", "(s (e - (e a)) <EOF>)",
|
||||
"-a+b", "(s (e (e - (e a)) + (e b)) <EOF>)",
|
||||
};
|
||||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
@Test public void testJavaExpressions() throws Exception {
|
||||
// Generates about 7k in bytecodes for generated e_ rule;
|
||||
// Well within the 64k method limit. e_primary compiles
|
||||
// to about 2k in bytecodes.
|
||||
// this is simplified from real java
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : e EOF ;\n" + // must indicate EOF can follow
|
||||
"expressionList\n" +
|
||||
" : e (',' e)*\n" +
|
||||
" ;\n" +
|
||||
"e : '(' e ')'\n" +
|
||||
" | 'this' \n" +
|
||||
" | 'super'\n" +
|
||||
" | INT\n" +
|
||||
" | ID\n" +
|
||||
" | type '.' 'class'\n" +
|
||||
" | e '.' ID\n" +
|
||||
" | e '.' 'this'\n" +
|
||||
" | e '.' 'super' '(' expressionList? ')'\n" +
|
||||
" | e '.' 'new' ID '(' expressionList? ')'\n" +
|
||||
" | 'new' type ( '(' expressionList? ')' | ('[' e ']')+)\n" +
|
||||
" | e '[' e ']'\n" +
|
||||
" | '(' type ')' e\n" +
|
||||
" | e ('++' | '--')\n" +
|
||||
" | e '(' expressionList? ')'\n" +
|
||||
" | ('+'|'-'|'++'|'--') e\n" +
|
||||
" | ('~'|'!') e\n" +
|
||||
" | e ('*'|'/'|'%') e\n" +
|
||||
" | e ('+'|'-') e\n" +
|
||||
" | e ('<<' | '>>>' | '>>') e\n" +
|
||||
" | e ('<=' | '>=' | '>' | '<') e\n" +
|
||||
" | e 'instanceof' e\n" +
|
||||
" | e ('==' | '!=') e\n" +
|
||||
" | e '&' e\n" +
|
||||
" |<assoc=right> e '^' e\n" +
|
||||
" | e '|' e\n" +
|
||||
" | e '&&' e\n" +
|
||||
" | e '||' e\n" +
|
||||
" | e '?' e ':' e\n" +
|
||||
" |<assoc=right>" +
|
||||
" e ('='\n" +
|
||||
" |'+='\n" +
|
||||
" |'-='\n" +
|
||||
" |'*='\n" +
|
||||
" |'/='\n" +
|
||||
" |'&='\n" +
|
||||
" |'|='\n" +
|
||||
" |'^='\n" +
|
||||
" |'>>='\n" +
|
||||
" |'>>>='\n" +
|
||||
" |'<<='\n" +
|
||||
" |'%=') e\n" +
|
||||
" ;\n" +
|
||||
"type: ID \n" +
|
||||
" | ID '[' ']'\n" +
|
||||
" | 'int'\n" +
|
||||
" | 'int' '[' ']' \n" +
|
||||
" ;\n" +
|
||||
"ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;\n" +
|
||||
"INT : '0'..'9'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String[] tests = {
|
||||
"a|b&c", "(s (e (e a) | (e (e b) & (e c))) <EOF>)",
|
||||
"(a|b)&c", "(s (e (e ( (e (e a) | (e b)) )) & (e c)) <EOF>)",
|
||||
"a > b", "(s (e (e a) > (e b)) <EOF>)",
|
||||
"a >> b", "(s (e (e a) >> (e b)) <EOF>)",
|
||||
"a=b=c", "(s (e (e a) = (e (e b) = (e c))) <EOF>)",
|
||||
"a^b^c", "(s (e (e a) ^ (e (e b) ^ (e c))) <EOF>)",
|
||||
"(T)x", "(s (e ( (type T) ) (e x)) <EOF>)",
|
||||
"new A().b", "(s (e (e new (type A) ( )) . b) <EOF>)",
|
||||
"(T)t.f()", "(s (e (e ( (type T) ) (e (e t) . f)) ( )) <EOF>)",
|
||||
"a.f(x)==T.c", "(s (e (e (e (e a) . f) ( (expressionList (e x)) )) == (e (e T) . c)) <EOF>)",
|
||||
"a.f().g(x,1)", "(s (e (e (e (e (e a) . f) ( )) . g) ( (expressionList (e x) , (e 1)) )) <EOF>)",
|
||||
"new T[((n-1) * x) + 1]", "(s (e new (type T) [ (e (e ( (e (e ( (e (e n) - (e 1)) )) * (e x)) )) + (e 1)) ]) <EOF>)",
|
||||
};
|
||||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
@Test public void testDeclarations() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : declarator EOF ;\n" + // must indicate EOF can follow
|
||||
"declarator\n" +
|
||||
" : declarator '[' e ']'\n" +
|
||||
" | declarator '[' ']'\n" +
|
||||
" | declarator '(' ')'\n" +
|
||||
" | '*' declarator\n" + // binds less tight than suffixes
|
||||
" | '(' declarator ')'\n" +
|
||||
" | ID\n" +
|
||||
" ;\n" +
|
||||
"e : INT ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String[] tests = {
|
||||
"a", "(s (declarator a) <EOF>)",
|
||||
"*a", "(s (declarator * (declarator a)) <EOF>)",
|
||||
"**a", "(s (declarator * (declarator * (declarator a))) <EOF>)",
|
||||
"a[3]", "(s (declarator (declarator a) [ (e 3) ]) <EOF>)",
|
||||
"b[]", "(s (declarator (declarator b) [ ]) <EOF>)",
|
||||
"(a)", "(s (declarator ( (declarator a) )) <EOF>)",
|
||||
"a[]()", "(s (declarator (declarator (declarator a) [ ]) ( )) <EOF>)",
|
||||
"a[][]", "(s (declarator (declarator (declarator a) [ ]) [ ]) <EOF>)",
|
||||
"*a[]", "(s (declarator * (declarator (declarator a) [ ])) <EOF>)",
|
||||
"(*a)[]", "(s (declarator (declarator ( (declarator * (declarator a)) )) [ ]) <EOF>)",
|
||||
};
|
||||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
@Test public void testReturnValueAndActions() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s : e {System.out.println($e.v);} ;\n" +
|
||||
"e returns [int v, List<String> ignored]\n" +
|
||||
" : a=e '*' b=e {$v = $a.v * $b.v;}\n" +
|
||||
" | a=e '+' b=e {$v = $a.v + $b.v;}\n" +
|
||||
" | INT {$v = $INT.int;}\n" +
|
||||
" | '(' x=e ')' {$v = $x.v;}\n" +
|
||||
" ;\n" +
|
||||
"INT : '0'..'9'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String[] tests = {
|
||||
"4", "4",
|
||||
"1+2", "3",
|
||||
"1+2*3", "7",
|
||||
"(1+2)*3", "9",
|
||||
};
|
||||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#677 "labels not working in
|
||||
* grammar file".
|
||||
* https://github.com/antlr/antlr4/issues/677
|
||||
*
|
||||
* <p>This test treats {@code ,} and {@code >>} as part of a single compound
|
||||
* operator (similar to a ternary operator).</p>
|
||||
*/
|
||||
@Test public void testReturnValueAndActionsList1() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : expr EOF;\n" +
|
||||
"expr:\n" +
|
||||
" a=expr '*' a=expr #Factor\n" +
|
||||
" | b+=expr (',' b+=expr)* '>>' c=expr #Send\n" +
|
||||
" | ID #JustId //semantic check on modifiers\n" +
|
||||
";\n" +
|
||||
"\n" +
|
||||
"ID : ('a'..'z'|'A'..'Z'|'_')\n" +
|
||||
" ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*\n" +
|
||||
";\n" +
|
||||
"\n" +
|
||||
"WS : [ \\t\\n]+ -> skip ;\n";
|
||||
String[] tests = {
|
||||
"a*b", "(s (expr (expr a) * (expr b)) <EOF>)",
|
||||
"a,c>>x", "(s (expr (expr a) , (expr c) >> (expr x)) <EOF>)",
|
||||
"x", "(s (expr x) <EOF>)",
|
||||
"a*b,c,x*y>>r", "(s (expr (expr (expr a) * (expr b)) , (expr c) , (expr (expr x) * (expr y)) >> (expr r)) <EOF>)",
|
||||
};
|
||||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#677 "labels not working in
|
||||
* grammar file".
|
||||
* https://github.com/antlr/antlr4/issues/677
|
||||
*
|
||||
* <p>This test treats the {@code ,} and {@code >>} operators separately.</p>
|
||||
*/
|
||||
@Test public void testReturnValueAndActionsList2() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : expr EOF;\n" +
|
||||
"expr:\n" +
|
||||
" a=expr '*' a=expr #Factor\n" +
|
||||
" | b+=expr ',' b+=expr #Comma\n" +
|
||||
" | b+=expr '>>' c=expr #Send\n" +
|
||||
" | ID #JustId //semantic check on modifiers\n" +
|
||||
";\n" +
|
||||
"\n" +
|
||||
"ID : ('a'..'z'|'A'..'Z'|'_')\n" +
|
||||
" ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*\n" +
|
||||
";\n" +
|
||||
"\n" +
|
||||
"WS : [ \\t\\n]+ -> skip ;\n";
|
||||
String[] tests = {
|
||||
"a*b", "(s (expr (expr a) * (expr b)) <EOF>)",
|
||||
"a,c>>x", "(s (expr (expr (expr a) , (expr c)) >> (expr x)) <EOF>)",
|
||||
"x", "(s (expr x) <EOF>)",
|
||||
"a*b,c,x*y>>r", "(s (expr (expr (expr (expr (expr a) * (expr b)) , (expr c)) , (expr (expr x) * (expr y))) >> (expr r)) <EOF>)",
|
||||
};
|
||||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
@Test public void testLabelsOnOpSubrule() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\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", "(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");
|
||||
}
|
||||
|
||||
@Test public void testReturnValueAndActionsAndLabels() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s : q=e {System.out.println($e.v);} ;\n" +
|
||||
"\n" +
|
||||
"e returns [int v]\n" +
|
||||
" : a=e op='*' b=e {$v = $a.v * $b.v;} # mult\n" +
|
||||
" | a=e '+' b=e {$v = $a.v + $b.v;} # add\n" +
|
||||
" | INT {$v = $INT.int;} # anInt\n" +
|
||||
" | '(' x=e ')' {$v = $x.v;} # parens\n" +
|
||||
" | x=e '++' {$v = $x.v+1;} # inc\n" +
|
||||
" | e '--' # dec\n" +
|
||||
" | ID {$v = 3;} # anID\n" +
|
||||
" ; \n" +
|
||||
"\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String[] tests = {
|
||||
"4", "4",
|
||||
"1+2", "3",
|
||||
"1+2*3", "7",
|
||||
"i++*3", "12",
|
||||
};
|
||||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#433 "Not all context accessor
|
||||
* methods are generated when an alternative rule label is used for multiple
|
||||
* alternatives".
|
||||
* https://github.com/antlr/antlr4/issues/433
|
||||
*/
|
||||
@Test public void testMultipleAlternativesWithCommonLabel() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s : e {System.out.println($e.v);} ;\n" +
|
||||
"\n" +
|
||||
"e returns [int v]\n" +
|
||||
" : e '*' e {$v = ((BinaryContext)$ctx).e(0).v * ((BinaryContext)$ctx).e(1).v;} # binary\n" +
|
||||
" | e '+' e {$v = ((BinaryContext)$ctx).e(0).v + ((BinaryContext)$ctx).e(1).v;} # binary\n" +
|
||||
" | INT {$v = $INT.int;} # anInt\n" +
|
||||
" | '(' e ')' {$v = $e.v;} # parens\n" +
|
||||
" | left=e INC {assert(((UnaryContext)$ctx).INC() != null); $v = $left.v + 1;} # unary\n" +
|
||||
" | left=e DEC {assert(((UnaryContext)$ctx).DEC() != null); $v = $left.v - 1;} # unary\n" +
|
||||
" | ID {$v = 3;} # anID\n" +
|
||||
" ; \n" +
|
||||
"\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+ ;\n" +
|
||||
"INC : '++' ;\n" +
|
||||
"DEC : '--' ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String[] tests = {
|
||||
"4", "4",
|
||||
"1+2", "3",
|
||||
"1+2*3", "7",
|
||||
"i++*3", "12",
|
||||
};
|
||||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
@Test public void testPrefixOpWithActionAndLabel() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s : e {System.out.println($e.result);} ;\n" +
|
||||
"\n" +
|
||||
"e returns [String result]\n" +
|
||||
" : ID '=' e1=e { $result = \"(\" + $ID.getText() + \"=\" + $e1.result + \")\"; }\n" +
|
||||
" | ID { $result = $ID.getText(); }\n" +
|
||||
" | e1=e '+' e2=e { $result = \"(\" + $e1.result + \"+\" + $e2.result + \")\"; }\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String[] tests = {
|
||||
"a", "a",
|
||||
"a+b", "(a+b)",
|
||||
"a=b+c", "((a=b)+c)",
|
||||
};
|
||||
runTests(grammar, tests, "s");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbigLR() throws Exception {
|
||||
String grammar =
|
||||
"grammar Expr;\n" +
|
||||
"prog: stat ;\n" +
|
||||
"stat: expr NEWLINE # printExpr\n" +
|
||||
" | ID '=' expr NEWLINE # assign\n" +
|
||||
" | NEWLINE # blank\n" +
|
||||
" ;\n" +
|
||||
"expr: expr ('*'|'/') expr # MulDiv\n" +
|
||||
" | expr ('+'|'-') expr # AddSub\n" +
|
||||
" | INT # int\n" +
|
||||
" | ID # id\n" +
|
||||
" | '(' expr ')' # parens\n" +
|
||||
" ;\n" +
|
||||
"\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";
|
||||
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);
|
||||
}
|
||||
|
||||
@Test public void testCheckForNonLeftRecursiveRule() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
|
@ -574,159 +64,4 @@ public class TestLeftRecursion extends BaseTest {
|
|||
testErrors(new String[] { grammar, expected }, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a regression test for #239 "recoursive parser using implicit
|
||||
* tokens ignore white space lexer rule".
|
||||
* https://github.com/antlr/antlr4/issues/239
|
||||
*/
|
||||
@Test public void testWhitespaceInfluence() {
|
||||
String grammar =
|
||||
"grammar Expr;\n" +
|
||||
"prog : expression EOF;\n" +
|
||||
"expression\n" +
|
||||
" : ID '(' expression (',' expression)* ')' # doFunction\n" +
|
||||
" | '(' expression ')' # doParenthesis\n" +
|
||||
" | '!' expression # doNot\n" +
|
||||
" | '-' expression # doNegate\n" +
|
||||
" | '+' expression # doPositiv\n" +
|
||||
" | expression '^' expression # doPower\n" +
|
||||
" | expression '*' expression # doMultipy\n" +
|
||||
" | expression '/' expression # doDivide\n" +
|
||||
" | expression '%' expression # doModulo\n" +
|
||||
" | expression '-' expression # doMinus\n" +
|
||||
" | expression '+' expression # doPlus\n" +
|
||||
" | expression '=' expression # doEqual\n" +
|
||||
" | expression '!=' expression # doNotEqual\n" +
|
||||
" | expression '>' expression # doGreather\n" +
|
||||
" | expression '>=' expression # doGreatherEqual\n" +
|
||||
" | expression '<' expression # doLesser\n" +
|
||||
" | expression '<=' expression # doLesserEqual\n" +
|
||||
" | expression K_IN '(' expression (',' expression)* ')' # doIn\n" +
|
||||
" | expression ( '&' | K_AND) expression # doAnd\n" +
|
||||
" | expression ( '|' | K_OR) expression # doOr\n" +
|
||||
" | '[' expression (',' expression)* ']' # newArray\n" +
|
||||
" | K_TRUE # newTrueBoolean\n" +
|
||||
" | K_FALSE # newFalseBoolean\n" +
|
||||
" | NUMBER # newNumber\n" +
|
||||
" | DATE # newDateTime\n" +
|
||||
" | ID # newIdentifier\n" +
|
||||
" | SQ_STRING # newString\n" +
|
||||
" | K_NULL # newNull\n" +
|
||||
" ;\n" +
|
||||
"\n" +
|
||||
"// Fragments\n" +
|
||||
"fragment DIGIT : '0' .. '9'; \n" +
|
||||
"fragment UPPER : 'A' .. 'Z';\n" +
|
||||
"fragment LOWER : 'a' .. 'z';\n" +
|
||||
"fragment LETTER : LOWER | UPPER;\n" +
|
||||
"fragment WORD : LETTER | '_' | '$' | '#' | '.';\n" +
|
||||
"fragment ALPHANUM : WORD | DIGIT; \n" +
|
||||
"\n" +
|
||||
"// Tokens\n" +
|
||||
"ID : LETTER ALPHANUM*;\n" +
|
||||
"NUMBER : DIGIT+ ('.' DIGIT+)? (('e'|'E')('+'|'-')? DIGIT+)?;\n" +
|
||||
"DATE : '\\'' DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT (' ' DIGIT DIGIT ':' DIGIT DIGIT ':' DIGIT DIGIT ('.' DIGIT+)?)? '\\'';\n" +
|
||||
"SQ_STRING : '\\'' ('\\'\\'' | ~'\\'')* '\\'';\n" +
|
||||
"DQ_STRING : '\"' ('\\\\\"' | ~'\"')* '\"';\n" +
|
||||
"WS : [ \\t\\n\\r]+ -> skip ;\n" +
|
||||
"COMMENTS : ('/*' .*? '*/' | '//' ~'\\n'* '\\n' ) -> skip;\n";
|
||||
|
||||
String expected =
|
||||
"";
|
||||
String result = execParser("Expr.g4", grammar, "ExprParser", "ExprLexer", "prog", "Test(1,3)", false);
|
||||
assertEquals(expected, result);
|
||||
assertNull(stderrDuringParse);
|
||||
|
||||
expected =
|
||||
"";
|
||||
result = execParser("Expr.g4", grammar, "ExprParser", "ExprLexer", "prog", "Test(1, 3)", false);
|
||||
assertEquals(expected, result);
|
||||
assertNull(stderrDuringParse);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#509 "Incorrect rule chosen in
|
||||
* unambiguous grammar".
|
||||
* https://github.com/antlr/antlr4/issues/509
|
||||
*/
|
||||
@Test public void testPrecedenceFilterConsidersContext() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"prog\n" +
|
||||
"@after {System.out.println($ctx.toStringTree(this));}\n" +
|
||||
": statement* EOF {};\n" +
|
||||
"statement: letterA | statement letterA 'b' ;\n" +
|
||||
"letterA: 'a';\n";
|
||||
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "prog",
|
||||
"aa", false);
|
||||
assertEquals("(prog (statement (letterA a)) (statement (letterA a)) <EOF>)\n", found);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#625 "Duplicate action breaks
|
||||
* operator precedence"
|
||||
* https://github.com/antlr/antlr4/issues/625
|
||||
*/
|
||||
@Test public void testMultipleActions() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\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", "(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");
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#625 "Duplicate action breaks
|
||||
* operator precedence"
|
||||
* https://github.com/antlr/antlr4/issues/625
|
||||
*/
|
||||
@Test public void testMultipleActionsPredicatesOptions() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"s @after {System.out.println($ctx.toStringTree(this));} : e ;\n" +
|
||||
"e : a=e op=('*'|'/') b=e {}{true}?\n" +
|
||||
" | a=e op=('+'|'-') b=e {}<p=3>{true}?<fail='Message'>\n" +
|
||||
" | INT {}{}\n" +
|
||||
" | '(' x=e ')' {}{}\n" +
|
||||
" ;\n" +
|
||||
"INT : '0'..'9'+ ;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;\n";
|
||||
String[] tests = {
|
||||
"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");
|
||||
}
|
||||
|
||||
public void runTests(String grammar, String[] tests, String startRule) {
|
||||
boolean success = rawGenerateAndBuildRecognizer("T.g4", grammar, "TParser", "TLexer");
|
||||
assertTrue(success);
|
||||
writeRecognizerAndCompile("TParser",
|
||||
"TLexer",
|
||||
startRule,
|
||||
debug,
|
||||
false);
|
||||
|
||||
for (int i=0; i<tests.length; i+=2) {
|
||||
String test = tests[i];
|
||||
String expecting = tests[i+1]+"\n";
|
||||
writeFile(tmpdir, "input", test);
|
||||
String found = execRecognizer();
|
||||
System.out.print(test+" -> "+found);
|
||||
assertEquals(expecting, found);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue