TestSemPredEvalParser for Java is working
This commit is contained in:
parent
42ba8c4530
commit
98bb519f8a
|
@ -1,7 +1,8 @@
|
|||
TestFolders ::= [
|
||||
"CompositeLexers": [],
|
||||
"LexerExec": [],
|
||||
"ParseTrees": []
|
||||
"ParseTrees": [],
|
||||
"SemPredEvalParser": []
|
||||
]
|
||||
|
||||
//TestTemplates ::= [
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
// We have n-2 predicates for n alternatives. pick first alt
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "x; y"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 1
|
||||
alt 1<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= <<
|
||||
line 1:0 reportAttemptingFullContext d=0 (a), input='x'
|
||||
line 1:0 reportAmbiguity d=0 (a): ambigAlts={1, 2}, input='x'
|
||||
line 1:3 reportAttemptingFullContext d=0 (a), input='y'
|
||||
line 1:3 reportAmbiguity d=0 (a): ambigAlts={1, 2}, input='y'<\n>
|
||||
>>
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : {<LL_EXACT_AMBIG_DETECTION()>} a ';' a; // do 2x: once in ATN, next in DFA
|
||||
a : ID {<writeln("\"alt 1\"")>}
|
||||
| ID {<writeln("\"alt 2\"")>}
|
||||
| {<False()>}? ID {<writeln("\"alt 3\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,39 @@
|
|||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "34; x; y"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 1
|
||||
alt 2
|
||||
alt 2<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= <<
|
||||
line 1:4 reportAttemptingFullContext d=0 (a), input='x'
|
||||
line 1:4 reportAmbiguity d=0 (a): ambigAlts={2, 3}, input='x'
|
||||
line 1:7 reportAttemptingFullContext d=0 (a), input='y'
|
||||
line 1:7 reportAmbiguity d=0 (a): ambigAlts={2, 3}, input='y'<\n>
|
||||
>>
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : {<LL_EXACT_AMBIG_DETECTION()>} a ';' a ';' a;
|
||||
a : INT {<writeln("\"alt 1\"")>}
|
||||
| ID {<writeln("\"alt 2\"")>} // must pick this one for ID since pred is false
|
||||
| ID {<writeln("\"alt 3\"")>}
|
||||
| {<False()>}? ID {<writeln("\"alt 4\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -1,3 +1,26 @@
|
|||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": false
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "x x y"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 1
|
||||
alt 1
|
||||
alt 1<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
@members {<InitIntMember("i","0")>}
|
||||
s : a+ ;
|
||||
|
@ -7,3 +30,4 @@ a : {<SetMember("i","1")>} ID {<MemberEquals("i","1")>}? {<writeln("\"alt 1\"")>
|
|||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,39 @@
|
|||
/** Regular non-forced actions can create side effects used by semantic
|
||||
* predicates and so we cannot evaluate any semantic predicate
|
||||
* encountered after having seen a regular action. This includes
|
||||
* during global follow operations.
|
||||
*/
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "a!"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
eval=true
|
||||
parse<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
@members {
|
||||
<Declare_pred()>
|
||||
}
|
||||
s : e {} {<True():Invoke_pred()>}? {<writeln("\"parse\"")>} '!' ;
|
||||
t : e {} {<False():Invoke_pred()>}? ID ;
|
||||
e : ID | ; // non-LL(1) so we use ATN
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,26 @@
|
|||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": false
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "a+b+a"
|
||||
|
||||
Rule() ::= "start"
|
||||
|
||||
Output() ::= ""
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
start : e[0] EOF;
|
||||
e[int _p]
|
||||
: ( 'a' | 'b'+ ) ( {3 >= $_p}? '+' e[4] )*
|
||||
;
|
||||
|
||||
>>
|
|
@ -0,0 +1,38 @@
|
|||
/** We cannot collect predicates that are dependent on local context if
|
||||
* we are doing a global follow. They appear as if they were not there at all.
|
||||
*/
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "a!"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
eval=true
|
||||
parse<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
@members {
|
||||
<Declare_pred()>
|
||||
}
|
||||
s : a[99] ;
|
||||
a[int i] : e {<ValEquals("$i","99"):Invoke_pred()>}? {<writeln("\"parse\"")>} '!' ;
|
||||
b[int i] : e {<ValEquals("$i","99"):Invoke_pred()>}? ID ;
|
||||
e : ID | ; // non-LL(1) so we use ATN
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -1,3 +1,26 @@
|
|||
// uses ID ';' or ID '.' lookahead to solve s. preds not tested.
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "a;"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 2<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : b[2] ';' | b[2] '.' ; // decision in s drills down to ctx-dependent pred in a;
|
||||
b[int i] : a[i] ;
|
||||
|
@ -9,3 +32,4 @@ ID : 'a'..'z'+ ;
|
|||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
|
||||
>>
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* This is a regression test for antlr/antlr4#218 "ANTLR4 EOF Related Bug".
|
||||
* https://github.com/antlr/antlr4/issues/218
|
||||
*/
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "hello"
|
||||
|
||||
Rule() ::= "cppCompilationUnit"
|
||||
|
||||
Output() ::= <<
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
cppCompilationUnit : content+ EOF;
|
||||
content: anything | {<False()>}? .;
|
||||
anything: ANY_CHAR;
|
||||
ANY_CHAR: [_a-zA-Z0-9];
|
||||
>>
|
|
@ -0,0 +1,32 @@
|
|||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "a;"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 2<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : b ';' | b '.' ;
|
||||
b : a ;
|
||||
a
|
||||
: {<False()>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<True()>}? ID {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,31 @@
|
|||
//TestFolders ::= [
|
||||
//]
|
||||
|
||||
TestTemplates ::= [
|
||||
"SimpleValidate": [],
|
||||
"SimpleValidate2": [],
|
||||
"AtomWithClosureInTranslatedLRRule": [],
|
||||
"ValidateInDFA": [],
|
||||
"Simple": [],
|
||||
"Order": [],
|
||||
"2UnpredicatedAlts": [],
|
||||
"2UnpredicatedAltsAndOneOrthogonalAlt": [],
|
||||
"RewindBeforePredEval": [],
|
||||
"NoTruePredsThrowsNoViableAlt": [],
|
||||
"ToLeft": [],
|
||||
"UnpredicatedPathsInAlt": [],
|
||||
"ActionHidesPreds": [],
|
||||
"ToLeftWithVaryingPredicate": [],
|
||||
"PredicateDependentOnArg": [],
|
||||
"PredicateDependentOnArg2": [],
|
||||
"DependentPredNotInOuterCtxShouldBeIgnored": [],
|
||||
"IndependentPredNotPassedOuterCtxToAvoidCastException": [],
|
||||
"PredsInGlobalFOLLOW": [],
|
||||
"DepedentPredsInGlobalFOLLOW": [],
|
||||
"ActionsHidePredsInGlobalFOLLOW": [],
|
||||
"PredTestedEvenWhenUnAmbig_1": [],
|
||||
"PredTestedEvenWhenUnAmbig_2": [],
|
||||
"DisabledAlternative": [],
|
||||
"PredFromAltTestedInLoopBack_1": [],
|
||||
"PredFromAltTestedInLoopBack_2": []
|
||||
]
|
|
@ -0,0 +1,34 @@
|
|||
// checks that we throw exception if all alts
|
||||
// are covered with a predicate and none succeeds
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": false
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "y 3 x 4"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
>>
|
||||
|
||||
Errors() ::= <<
|
||||
line 1:0 no viable alternative at input 'y'<\n>
|
||||
>>
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : a a;
|
||||
a : {<False()>}? ID INT {<writeln("\"alt 1\"")>}
|
||||
| {<False()>}? ID INT {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,37 @@
|
|||
// Under new predicate ordering rules (see antlr/antlr4#29), the first
|
||||
// alt with an acceptable config (unpredicated, or predicated and evaluates
|
||||
// to true) is chosen.
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": false
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "x y"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 1
|
||||
alt 1<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : a {} a; // do 2x: once in ATN, next in DFA;
|
||||
// action blocks lookahead from falling off of 'a'
|
||||
// and looking into 2nd 'a' ref. !ctx dependent pred
|
||||
a : ID {<writeln("\"alt 1\"")>}
|
||||
| {<True()>}? ID {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -1,3 +1,18 @@
|
|||
/** Loopback doesn't eval predicate at start of alt */
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Rule() ::= "file_"
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
file_
|
||||
@after {<ToStringTree("$ctx"):writeln()>}
|
||||
|
@ -7,3 +22,4 @@ paraContent : ('s'|'x'|{<LANotEquals("2","NL")>}? NL)+ ;
|
|||
NL : '\n' ;
|
||||
s : 's' ;
|
||||
X : 'x' ;
|
||||
>>
|
|
@ -0,0 +1,12 @@
|
|||
import "PredFromAltTestedInLoopBack.stg"
|
||||
|
||||
Input() ::= "s<\n><\n><\n>x<\n>"
|
||||
|
||||
Output() ::= <<
|
||||
(file_ (para (paraContent s) \n \n) (para (paraContent \n x \n)) \<EOF>)<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= <<
|
||||
line 5:0 mismatched input '\<EOF>' expecting '
|
||||
'<\n>
|
||||
>>
|
|
@ -0,0 +1,9 @@
|
|||
import "PredFromAltTestedInLoopBack.stg"
|
||||
|
||||
Input() ::= "s<\n><\n><\n>x<\n><\n>"
|
||||
|
||||
Output() ::= <<
|
||||
(file_ (para (paraContent s) \n \n) (para (paraContent \n x) \n \n) \<EOF>)<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
|
@ -1,3 +1,16 @@
|
|||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Rule() ::= "primary"
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
@members {<InitBooleanMember("enumKeyword",True())>}
|
||||
primary
|
||||
|
@ -6,3 +19,4 @@ primary
|
|||
;
|
||||
ID : [a-z]+ ;
|
||||
WS : [ \t\n\r]+ -> skip ;
|
||||
>>
|
|
@ -0,0 +1,9 @@
|
|||
import "PredTestedEvenWhenUnAmbig.stg"
|
||||
|
||||
Input() ::= "abc"
|
||||
|
||||
Output() ::= <<
|
||||
ID abc<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
|
@ -0,0 +1,10 @@
|
|||
import "PredTestedEvenWhenUnAmbig.stg"
|
||||
|
||||
Input() ::= "enum"
|
||||
|
||||
Output() ::= <<
|
||||
>>
|
||||
|
||||
Errors() ::= <<
|
||||
line 1:0 no viable alternative at input 'enum'<\n>
|
||||
>>
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* In this case, we're passing a parameter into a rule that uses that
|
||||
* information to predict the alternatives. This is the special case
|
||||
* where we know exactly which context we are in. The context stack
|
||||
* is empty and we have not dipped into the outer context to make a decision.
|
||||
*/
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "a b"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 2
|
||||
alt 1<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
@members {<InitIntMember("i","0")>}
|
||||
s : a[2] a[1];
|
||||
a[int i]
|
||||
: {<ValEquals("$i","1")>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<ValEquals("$i","2")>}? ID {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* In this case, we have to ensure that the predicates are not tested
|
||||
* during the closure after recognizing the 1st ID. The closure will
|
||||
* fall off the end of 'a' 1st time and reach into the a[1] rule
|
||||
* invocation. It should not execute predicates because it does not know
|
||||
* what the parameter is. The context stack will not be empty and so
|
||||
* they should be ignored. It will not affect recognition, however. We
|
||||
* are really making sure the ATN simulation doesn't crash with context
|
||||
* object issues when it encounters preds during FOLLOW.
|
||||
*/
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "a b"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
@members {<InitIntMember("i","0")>}
|
||||
s : a[2] a[1];
|
||||
a[int i]
|
||||
: {<ValEquals("$i","1")>}? ID
|
||||
| {<ValEquals("$i","2")>}? ID
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,38 @@
|
|||
/** During a global follow operation, we still collect semantic
|
||||
* predicates as long as they are not dependent on local context
|
||||
*/
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "a!"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
eval=true
|
||||
<! now we are parsing !>
|
||||
parse<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
@members {
|
||||
<Declare_pred()>
|
||||
}
|
||||
s : e {<True():Invoke_pred()>}? {<writeln("\"parse\"")>} '!' ;
|
||||
t : e {<False():Invoke_pred()>}? ID ;
|
||||
e : ID | ; // non-LL(1) so we use ATN
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,35 @@
|
|||
// The parser consumes ID and moves to the 2nd token INT.
|
||||
// To properly evaluate the predicates after matching ID INT,
|
||||
// we must correctly see come back to starting index so LT(1) works
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "y 3 x 4"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 2
|
||||
alt 1<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : a a;
|
||||
a : {<LTEquals("1", "\"x\"")>}? ID INT {<writeln("\"alt 1\"")>}
|
||||
| {<LTEquals("1", "\"y\"")>}? ID INT {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -1,3 +1,26 @@
|
|||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "x y 3"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 2
|
||||
alt 2
|
||||
alt 3<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : a a a; // do 3x: once in ATN, next in DFA then INT in ATN
|
||||
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
|
||||
|
@ -7,3 +30,4 @@ a : {<False()>}? ID {<writeln("\"alt 1\"")>}
|
|||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,30 @@
|
|||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "x"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= ""
|
||||
|
||||
Errors() ::= <<
|
||||
line 1:0 no viable alternative at input 'x'<\n>
|
||||
>>
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : a ;
|
||||
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<True()>}? INT {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,33 @@
|
|||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "3 4 x"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 2
|
||||
alt 2<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= <<
|
||||
line 1:4 no viable alternative at input 'x'<\n>
|
||||
>>
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : a a a;
|
||||
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<True()>}? INT {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,32 @@
|
|||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "x x y"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 2
|
||||
alt 2
|
||||
alt 2<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : a+ ;
|
||||
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<True()>}? ID {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,43 @@
|
|||
/** In this case, we use predicates that depend on global information
|
||||
* like we would do for a symbol table. We simply execute
|
||||
* the predicates assuming that all necessary information is available.
|
||||
* The i++ action is done outside of the prediction and so it is executed.
|
||||
*/
|
||||
|
||||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "x x y"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
i=1
|
||||
alt 2
|
||||
i=2
|
||||
alt 1
|
||||
i=3
|
||||
alt 2<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
@members {<InitIntMember("i","0")>}
|
||||
s : ({<AddMember("i","1")>
|
||||
<PlusMember("\"i=\"","i"):writeln()>} a)+ ;
|
||||
a : {<ModMemberEquals("i","2","0")>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<ModMemberNotEquals("i","2","0")>}? ID {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -0,0 +1,34 @@
|
|||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "x 4"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
alt 1<\n>
|
||||
>>
|
||||
|
||||
Errors() ::= ""
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : a {<writeln("\"alt 1\"")>}
|
||||
| b {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
a : {<False()>}? ID INT
|
||||
| ID INT
|
||||
;
|
||||
b : ID ID
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -1,3 +1,26 @@
|
|||
TestType() ::= "Parser"
|
||||
|
||||
Options ::= [
|
||||
"Debug": true
|
||||
]
|
||||
|
||||
Grammar ::= [
|
||||
"T": {<grammar("T")>}
|
||||
]
|
||||
|
||||
Input() ::= "x ; y"
|
||||
|
||||
Rule() ::= "s"
|
||||
|
||||
Output() ::= <<
|
||||
>>
|
||||
|
||||
Errors() ::= <<
|
||||
line 1:0 no viable alternative at input 'x'
|
||||
line 1:4 no viable alternative at input 'y'<\n>
|
||||
>>
|
||||
|
||||
grammar(grammarName) ::= <<
|
||||
grammar <grammarName>;
|
||||
s : a ';' a;
|
||||
// ';' helps us to resynchronize without consuming
|
||||
|
@ -9,3 +32,4 @@ a : {<False()>}? ID {<writeln("\"alt 1\"")>}
|
|||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
||||
>>
|
|
@ -109,7 +109,7 @@ public class Antlr4TestGeneratorMojo extends AbstractMojo {
|
|||
List<ST> templates = new ArrayList<ST>();
|
||||
for (String template : testTemplates) {
|
||||
STGroup testGroup = new STGroupFile(templateFolder + "/" + template + STGroup.GROUP_FILE_EXTENSION);
|
||||
testGroup.importTemplates(targetGroup);
|
||||
importLanguageTemplates(testGroup, targetGroup);
|
||||
ST testType = testGroup.getInstanceOf("TestType");
|
||||
if (testType == null) {
|
||||
getLog().warn(String.format("Unable to generate tests for %s: no TestType specified.", template));
|
||||
|
@ -143,6 +143,29 @@ public class Antlr4TestGeneratorMojo extends AbstractMojo {
|
|||
}
|
||||
}
|
||||
|
||||
private void importLanguageTemplates(STGroup testGroup, STGroup languageGroup) {
|
||||
// make sure the test group is loaded
|
||||
testGroup.load();
|
||||
|
||||
if (testGroup == languageGroup) {
|
||||
assert false : "Attempted to import the language group into itself.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (testGroup.getImportedGroups().isEmpty()) {
|
||||
testGroup.importTemplates(languageGroup);
|
||||
return;
|
||||
}
|
||||
|
||||
if (testGroup.getImportedGroups().contains(languageGroup)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (STGroup importedGroup : testGroup.getImportedGroups()) {
|
||||
importLanguageTemplates(importedGroup, languageGroup);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeFile(File file, String content) throws IOException {
|
||||
file.getParentFile().mkdirs();
|
||||
|
||||
|
|
|
@ -6,16 +6,16 @@
|
|||
package org.antlr.mojo.antlr4.testgen;
|
||||
|
||||
import org.stringtemplate.v4.Interpreter;
|
||||
import org.stringtemplate.v4.ModelAdaptor;
|
||||
import org.stringtemplate.v4.ST;
|
||||
import org.stringtemplate.v4.STGroup;
|
||||
import org.stringtemplate.v4.misc.ObjectModelAdaptor;
|
||||
import org.stringtemplate.v4.misc.STNoSuchPropertyException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sam
|
||||
*/
|
||||
public class STGroupModelAdaptor extends ObjectModelAdaptor {
|
||||
public class STGroupModelAdaptor implements ModelAdaptor {
|
||||
|
||||
@Override
|
||||
public Object getProperty(Interpreter interp, ST self, Object o, Object property, String propertyName) throws STNoSuchPropertyException {
|
||||
|
@ -29,7 +29,18 @@ public class STGroupModelAdaptor extends ObjectModelAdaptor {
|
|||
return template;
|
||||
}
|
||||
|
||||
return super.getProperty(interp, self, o, property, propertyName);
|
||||
if ("name".equalsIgnoreCase(propertyName)) {
|
||||
return group.getName();
|
||||
}
|
||||
|
||||
for (STGroup importedGroup : group.getImportedGroups()) {
|
||||
Object result = getProperty(interp, self, importedGroup, property, propertyName);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -158,188 +158,9 @@ public class Generator {
|
|||
list.add(buildParserErrors());
|
||||
list.add(buildParserExec());
|
||||
list.add(buildSemPredEvalLexer());
|
||||
list.add(buildSemPredEvalParser());
|
||||
return list;
|
||||
}
|
||||
|
||||
private JUnitTestFile buildSemPredEvalParser() throws Exception {
|
||||
JUnitTestFile file = new JUnitTestFile("SemPredEvalParser");
|
||||
JUnitTestMethod tm = file.addParserTest(input, "SimpleValidate", "T", "s",
|
||||
"x",
|
||||
"",
|
||||
"line 1:0 no viable alternative at input 'x'\n");
|
||||
tm.debug = true;
|
||||
tm = file.addParserTest(input, "SimpleValidate2", "T", "s",
|
||||
"3 4 x",
|
||||
"alt 2\n" + "alt 2\n",
|
||||
"line 1:4 no viable alternative at input 'x'\n");
|
||||
tm.debug = true;
|
||||
file.addParserTest(input, "AtomWithClosureInTranslatedLRRule", "T", "start",
|
||||
"a+b+a",
|
||||
"",
|
||||
null);
|
||||
tm = file.addParserTest(input, "ValidateInDFA", "T", "s",
|
||||
"x ; y",
|
||||
"",
|
||||
"line 1:0 no viable alternative at input 'x'\n" +
|
||||
"line 1:4 no viable alternative at input 'y'\n");
|
||||
tm.debug = true;
|
||||
tm = file.addParserTest(input, "Simple", "T", "s",
|
||||
"x y 3",
|
||||
"alt 2\n" + "alt 2\n" + "alt 3\n",
|
||||
null);
|
||||
// Under new predicate ordering rules (see antlr/antlr4#29), the first
|
||||
// alt with an acceptable config (unpredicated, or predicated and evaluates
|
||||
// to true) is chosen.
|
||||
tm.debug = true;
|
||||
file.addParserTest(input, "Order", "T", "s",
|
||||
"x y",
|
||||
"alt 1\n" + "alt 1\n",
|
||||
null);
|
||||
// We have n-2 predicates for n alternatives. pick first alt
|
||||
tm = file.addParserTest(input, "2UnpredicatedAlts", "T", "s",
|
||||
"x; y",
|
||||
"alt 1\n" +
|
||||
"alt 1\n",
|
||||
"line 1:0 reportAttemptingFullContext d=0 (a), input='x'\n" +
|
||||
"line 1:0 reportAmbiguity d=0 (a): ambigAlts={1, 2}, input='x'\n" +
|
||||
"line 1:3 reportAttemptingFullContext d=0 (a), input='y'\n" +
|
||||
"line 1:3 reportAmbiguity d=0 (a): ambigAlts={1, 2}, input='y'\n");
|
||||
tm.debug = true;
|
||||
tm = file.addParserTest(input, "2UnpredicatedAltsAndOneOrthogonalAlt", "T", "s",
|
||||
"34; x; y",
|
||||
"alt 1\n" + "alt 2\n" + "alt 2\n",
|
||||
"line 1:4 reportAttemptingFullContext d=0 (a), input='x'\n" +
|
||||
"line 1:4 reportAmbiguity d=0 (a): ambigAlts={2, 3}, input='x'\n" +
|
||||
"line 1:7 reportAttemptingFullContext d=0 (a), input='y'\n" +
|
||||
"line 1:7 reportAmbiguity d=0 (a): ambigAlts={2, 3}, input='y'\n");
|
||||
// The parser consumes ID and moves to the 2nd token INT.
|
||||
// To properly evaluate the predicates after matching ID INT,
|
||||
// we must correctly see come back to starting index so LT(1) works
|
||||
tm.debug = true;
|
||||
tm = file.addParserTest(input, "RewindBeforePredEval", "T", "s",
|
||||
"y 3 x 4",
|
||||
"alt 2\n" + "alt 1\n",
|
||||
null);
|
||||
// checks that we throw exception if all alts
|
||||
// are covered with a predicate and none succeeds
|
||||
tm.debug = true;
|
||||
file.addParserTest(input, "NoTruePredsThrowsNoViableAlt", "T", "s",
|
||||
"y 3 x 4",
|
||||
"",
|
||||
"line 1:0 no viable alternative at input 'y'\n");
|
||||
tm = file.addParserTest(input, "ToLeft", "T", "s",
|
||||
"x x y",
|
||||
"alt 2\n" + "alt 2\n" + "alt 2\n",
|
||||
null);
|
||||
tm.debug = true;
|
||||
tm = file.addParserTest(input, "UnpredicatedPathsInAlt", "T", "s",
|
||||
"x 4",
|
||||
"alt 1\n",
|
||||
null);
|
||||
tm.debug = true;
|
||||
file.addParserTest(input, "ActionHidesPreds", "T", "s",
|
||||
"x x y",
|
||||
"alt 1\n" + "alt 1\n" + "alt 1\n",
|
||||
null);
|
||||
/** In this case, we use predicates that depend on global information
|
||||
* like we would do for a symbol table. We simply execute
|
||||
* the predicates assuming that all necessary information is available.
|
||||
* The i++ action is done outside of the prediction and so it is executed.
|
||||
*/
|
||||
tm = file.addParserTest(input, "ToLeftWithVaryingPredicate", "T", "s",
|
||||
"x x y",
|
||||
"i=1\n" + "alt 2\n" + "i=2\n" + "alt 1\n" + "i=3\n" + "alt 2\n",
|
||||
null);
|
||||
tm.debug = true;
|
||||
/**
|
||||
* In this case, we're passing a parameter into a rule that uses that
|
||||
* information to predict the alternatives. This is the special case
|
||||
* where we know exactly which context we are in. The context stack
|
||||
* is empty and we have not dipped into the outer context to make a decision.
|
||||
*/
|
||||
tm = file.addParserTest(input, "PredicateDependentOnArg", "T", "s",
|
||||
"a b",
|
||||
"alt 2\n" + "alt 1\n",
|
||||
null);
|
||||
tm.debug = true;
|
||||
/** In this case, we have to ensure that the predicates are not
|
||||
tested during the closure after recognizing the 1st ID. The
|
||||
closure will fall off the end of 'a' 1st time and reach into the
|
||||
a[1] rule invocation. It should not execute predicates because it
|
||||
does not know what the parameter is. The context stack will not
|
||||
be empty and so they should be ignored. It will not affect
|
||||
recognition, however. We are really making sure the ATN
|
||||
simulation doesn't crash with context object issues when it
|
||||
encounters preds during FOLLOW.
|
||||
*/
|
||||
tm = file.addParserTest(input, "PredicateDependentOnArg2", "T", "s",
|
||||
"a b",
|
||||
"",
|
||||
null);
|
||||
tm.debug = true;
|
||||
// uses ID ';' or ID '.' lookahead to solve s. preds not tested.
|
||||
tm = file.addParserTest(input, "DependentPredNotInOuterCtxShouldBeIgnored", "T", "s",
|
||||
"a;",
|
||||
"alt 2\n",
|
||||
null);
|
||||
tm.debug = true;
|
||||
tm = file.addParserTest(input, "IndependentPredNotPassedOuterCtxToAvoidCastException", "T", "s",
|
||||
"a;",
|
||||
"alt 2\n",
|
||||
null);
|
||||
tm.debug = true;
|
||||
/** During a global follow operation, we still collect semantic
|
||||
* predicates as long as they are not dependent on local context
|
||||
*/
|
||||
tm = file.addParserTest(input, "PredsInGlobalFOLLOW", "T", "s",
|
||||
"a!",
|
||||
"eval=true\n" + /* now we are parsing */ "parse\n",
|
||||
null);
|
||||
tm.debug = true;
|
||||
/** We cannot collect predicates that are dependent on local context if
|
||||
* we are doing a global follow. They appear as if they were not there at all.
|
||||
*/
|
||||
tm = file.addParserTest(input, "DepedentPredsInGlobalFOLLOW","T", "s",
|
||||
"a!",
|
||||
"eval=true\n" + "parse\n",
|
||||
null);
|
||||
tm.debug = true;
|
||||
/** Regular non-forced actions can create side effects used by semantic
|
||||
* predicates and so we cannot evaluate any semantic predicate
|
||||
* encountered after having seen a regular action. This includes
|
||||
* during global follow operations.
|
||||
*/
|
||||
tm = file.addParserTest(input, "ActionsHidePredsInGlobalFOLLOW", "T", "s",
|
||||
"a!",
|
||||
"eval=true\n" + "parse\n",
|
||||
null);
|
||||
tm.debug = true;
|
||||
tm = file.addParserTestsWithErrors(input, "PredTestedEvenWhenUnAmbig", "T", "primary",
|
||||
"abc", "ID abc\n", null,
|
||||
"enum", "", "line 1:0 no viable alternative at input 'enum'\n");
|
||||
tm.debug = true;
|
||||
/**
|
||||
* This is a regression test for antlr/antlr4#218 "ANTLR4 EOF Related Bug".
|
||||
* https://github.com/antlr/antlr4/issues/218
|
||||
*/
|
||||
tm = file.addParserTest(input, "DisabledAlternative", "T", "cppCompilationUnit",
|
||||
"hello",
|
||||
"",
|
||||
null);
|
||||
tm.debug = true;
|
||||
/** Loopback doesn't eval predicate at start of alt */
|
||||
tm = file.addParserTestsWithErrors(input, "PredFromAltTestedInLoopBack", "T", "file_",
|
||||
"s\n\n\nx\n",
|
||||
"(file_ (para (paraContent s) \\n \\n) (para (paraContent \\n x \\n)) <EOF>)\n",
|
||||
"line 5:0 mismatched input '<EOF>' expecting '\n'\n",
|
||||
"s\n\n\nx\n\n",
|
||||
"(file_ (para (paraContent s) \\n \\n) (para (paraContent \\n x) \\n \\n) <EOF>)\n",
|
||||
null);
|
||||
tm.debug = true;
|
||||
return file;
|
||||
}
|
||||
|
||||
private JUnitTestFile buildSemPredEvalLexer() throws Exception {
|
||||
JUnitTestFile file = new JUnitTestFile("SemPredEvalLexer");
|
||||
LexerTestMethod tm = file.addLexerTest(input, "DisableRule", "L",
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
s : {<LL_EXACT_AMBIG_DETECTION()>} a ';' a; // do 2x: once in ATN, next in DFA
|
||||
a : ID {<writeln("\"alt 1\"")>}
|
||||
| ID {<writeln("\"alt 2\"")>}
|
||||
| {<False()>}? ID {<writeln("\"alt 3\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,10 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
s : {<LL_EXACT_AMBIG_DETECTION()>} a ';' a ';' a;
|
||||
a : INT {<writeln("\"alt 1\"")>}
|
||||
| ID {<writeln("\"alt 2\"")>} // must pick this one for ID since pred is false
|
||||
| ID {<writeln("\"alt 3\"")>}
|
||||
| {<False()>}? ID {<writeln("\"alt 4\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,10 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
@members {
|
||||
<Declare_pred()>
|
||||
}
|
||||
s : e {} {<True():Invoke_pred()>}? {<writeln("\"parse\"")>} '!' ;
|
||||
t : e {} {<False():Invoke_pred()>}? ID ;
|
||||
e : ID | ; // non-LL(1) so we use ATN
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,6 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
start : e[0] EOF;
|
||||
e[int _p]
|
||||
: ( 'a' | 'b'+ ) ( {3 >= $_p}? '+' e[4] )*
|
||||
;
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
@members {
|
||||
<Declare_pred()>
|
||||
}
|
||||
s : a[99] ;
|
||||
a[int i] : e {<ValEquals("$i","99"):Invoke_pred()>}? {<writeln("\"parse\"")>} '!' ;
|
||||
b[int i] : e {<ValEquals("$i","99"):Invoke_pred()>}? ID ;
|
||||
e : ID | ; // non-LL(1) so we use ATN
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,5 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
cppCompilationUnit : content+ EOF;
|
||||
content: anything | {<False()>}? .;
|
||||
anything: ANY_CHAR;
|
||||
ANY_CHAR: [_a-zA-Z0-9];
|
|
@ -1,10 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
s : b ';' | b '.' ;
|
||||
b : a ;
|
||||
a
|
||||
: {<False()>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<True()>}? ID {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,8 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
s : a a;
|
||||
a : {<False()>}? ID INT {<writeln("\"alt 1\"")>}
|
||||
| {<False()>}? ID INT {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,10 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
s : a {} a; // do 2x: once in ATN, next in DFA;
|
||||
// action blocks lookahead from falling off of 'a'
|
||||
// and looking into 2nd 'a' ref. !ctx dependent pred
|
||||
a : ID {<writeln("\"alt 1\"")>}
|
||||
| {<True()>}? ID {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,10 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
@members {<InitIntMember("i","0")>}
|
||||
s : a[2] a[1];
|
||||
a[int i]
|
||||
: {<ValEquals("$i","1")>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<ValEquals("$i","2")>}? ID {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,10 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
@members {<InitIntMember("i","0")>}
|
||||
s : a[2] a[1];
|
||||
a[int i]
|
||||
: {<ValEquals("$i","1")>}? ID
|
||||
| {<ValEquals("$i","2")>}? ID
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,10 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
@members {
|
||||
<Declare_pred()>
|
||||
}
|
||||
s : e {<True():Invoke_pred()>}? {<writeln("\"parse\"")>} '!' ;
|
||||
t : e {<False():Invoke_pred()>}? ID ;
|
||||
e : ID | ; // non-LL(1) so we use ATN
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,8 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
s : a a;
|
||||
a : {<LTEquals("1", "\"x\"")>}? ID INT {<writeln("\"alt 1\"")>}
|
||||
| {<LTEquals("1", "\"y\"")>}? ID INT {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,8 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
s : a ;
|
||||
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<True()>}? INT {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,8 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
s : a a a;
|
||||
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<True()>}? INT {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,8 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
s : a+ ;
|
||||
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<True()>}? ID {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,10 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
@members {<InitIntMember("i","0")>}
|
||||
s : ({<AddMember("i","1")>
|
||||
<PlusMember("\"i=\"","i"):writeln()>} a)+ ;
|
||||
a : {<ModMemberEquals("i","2","0")>}? ID {<writeln("\"alt 1\"")>}
|
||||
| {<ModMemberNotEquals("i","2","0")>}? ID {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,12 +0,0 @@
|
|||
grammar <grammarName>;
|
||||
s : a {<writeln("\"alt 1\"")>}
|
||||
| b {<writeln("\"alt 2\"")>}
|
||||
;
|
||||
a : {<False()>}? ID INT
|
||||
| ID INT
|
||||
;
|
||||
b : ID ID
|
||||
;
|
||||
ID : 'a'..'z'+ ;
|
||||
INT : '0'..'9'+;
|
||||
WS : (' '|'\n') -> skip ;
|
|
@ -1,454 +0,0 @@
|
|||
package org.antlr.v4.test.rt.java;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class TestSemPredEvalParser extends BaseTest {
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testSimpleValidate() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : a ;\n" +
|
||||
"a : {false}? ID {System.out.println(\"alt 1\");}\n" +
|
||||
" | {true}? INT {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "x", true);
|
||||
assertEquals("", found);
|
||||
assertEquals("line 1:0 no viable alternative at input 'x'\n", this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testSimpleValidate2() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : a a a;\n" +
|
||||
"a : {false}? ID {System.out.println(\"alt 1\");}\n" +
|
||||
" | {true}? INT {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "3 4 x", true);
|
||||
assertEquals("alt 2\nalt 2\n", found);
|
||||
assertEquals("line 1:4 no viable alternative at input 'x'\n", this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testAtomWithClosureInTranslatedLRRule() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"start : e[0] EOF;\n" +
|
||||
"e[int _p]\n" +
|
||||
" : ( 'a' | 'b'+ ) ( {3 >= $_p}? '+' e[4] )*\n" +
|
||||
" ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", "a+b+a", false);
|
||||
assertEquals("", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testValidateInDFA() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : a ';' a;\n" +
|
||||
"// ';' helps us to resynchronize without consuming\n" +
|
||||
"// 2nd 'a' reference. We our testing that the DFA also\n" +
|
||||
"// throws an exception if the validating predicate fails\n" +
|
||||
"a : {false}? ID {System.out.println(\"alt 1\");}\n" +
|
||||
" | {true}? INT {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "x ; y", true);
|
||||
assertEquals("", found);
|
||||
assertEquals("line 1:0 no viable alternative at input 'x'\nline 1:4 no viable alternative at input 'y'\n", this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testSimple() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : a a a; // do 3x: once in ATN, next in DFA then INT in ATN\n" +
|
||||
"a : {false}? ID {System.out.println(\"alt 1\");}\n" +
|
||||
" | {true}? ID {System.out.println(\"alt 2\");}\n" +
|
||||
" | INT {System.out.println(\"alt 3\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "x y 3", true);
|
||||
assertEquals("alt 2\nalt 2\nalt 3\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testOrder() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : a {} a; // do 2x: once in ATN, next in DFA;\n" +
|
||||
"// action blocks lookahead from falling off of 'a'\n" +
|
||||
"// and looking into 2nd 'a' ref. !ctx dependent pred\n" +
|
||||
"a : ID {System.out.println(\"alt 1\");}\n" +
|
||||
" | {true}? ID {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "x y", false);
|
||||
assertEquals("alt 1\nalt 1\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void test2UnpredicatedAlts() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);} a ';' a; // do 2x: once in ATN, next in DFA\n" +
|
||||
"a : ID {System.out.println(\"alt 1\");}\n" +
|
||||
" | ID {System.out.println(\"alt 2\");}\n" +
|
||||
" | {false}? ID {System.out.println(\"alt 3\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "x; y", true);
|
||||
assertEquals("alt 1\nalt 1\n", found);
|
||||
assertEquals("line 1:0 reportAttemptingFullContext d=0 (a), input='x'\nline 1:0 reportAmbiguity d=0 (a): ambigAlts={1, 2}, input='x'\nline 1:3 reportAttemptingFullContext d=0 (a), input='y'\nline 1:3 reportAmbiguity d=0 (a): ambigAlts={1, 2}, input='y'\n", this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void test2UnpredicatedAltsAndOneOrthogonalAlt() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);} a ';' a ';' a;\n" +
|
||||
"a : INT {System.out.println(\"alt 1\");}\n" +
|
||||
" | ID {System.out.println(\"alt 2\");} // must pick this one for ID since pred is false\n" +
|
||||
" | ID {System.out.println(\"alt 3\");}\n" +
|
||||
" | {false}? ID {System.out.println(\"alt 4\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "34; x; y", true);
|
||||
assertEquals("alt 1\nalt 2\nalt 2\n", found);
|
||||
assertEquals("line 1:4 reportAttemptingFullContext d=0 (a), input='x'\nline 1:4 reportAmbiguity d=0 (a): ambigAlts={2, 3}, input='x'\nline 1:7 reportAttemptingFullContext d=0 (a), input='y'\nline 1:7 reportAmbiguity d=0 (a): ambigAlts={2, 3}, input='y'\n", this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testRewindBeforePredEval() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : a a;\n" +
|
||||
"a : {this._input.LT(1).getText().equals(\"x\")}? ID INT {System.out.println(\"alt 1\");}\n" +
|
||||
" | {this._input.LT(1).getText().equals(\"y\")}? ID INT {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "y 3 x 4", true);
|
||||
assertEquals("alt 2\nalt 1\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testNoTruePredsThrowsNoViableAlt() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : a a;\n" +
|
||||
"a : {false}? ID INT {System.out.println(\"alt 1\");}\n" +
|
||||
" | {false}? ID INT {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "y 3 x 4", false);
|
||||
assertEquals("", found);
|
||||
assertEquals("line 1:0 no viable alternative at input 'y'\n", this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testToLeft() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
" s : a+ ;\n" +
|
||||
"a : {false}? ID {System.out.println(\"alt 1\");}\n" +
|
||||
" | {true}? ID {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "x x y", true);
|
||||
assertEquals("alt 2\nalt 2\nalt 2\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testUnpredicatedPathsInAlt() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : a {System.out.println(\"alt 1\");}\n" +
|
||||
" | b {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"a : {false}? ID INT\n" +
|
||||
" | ID INT\n" +
|
||||
" ;\n" +
|
||||
"b : ID ID\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "x 4", true);
|
||||
assertEquals("alt 1\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testActionHidesPreds() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"@members {int i = 0;}\n" +
|
||||
"s : a+ ;\n" +
|
||||
"a : {this.i = 1;} ID {this.i == 1}? {System.out.println(\"alt 1\");}\n" +
|
||||
" | {this.i = 2;} ID {this.i == 2}? {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "x x y", false);
|
||||
assertEquals("alt 1\nalt 1\nalt 1\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testToLeftWithVaryingPredicate() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"@members {int i = 0;}\n" +
|
||||
"s : ({this.i += 1;\n" +
|
||||
"System.out.println(\"i=\" + this.i);} a)+ ;\n" +
|
||||
"a : {this.i % 2 == 0}? ID {System.out.println(\"alt 1\");}\n" +
|
||||
" | {this.i % 2 != 0}? ID {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "x x y", true);
|
||||
assertEquals("i=1\nalt 2\ni=2\nalt 1\ni=3\nalt 2\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testPredicateDependentOnArg() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"@members {int i = 0;}\n" +
|
||||
"s : a[2] a[1];\n" +
|
||||
"a[int i]\n" +
|
||||
" : {$i==1}? ID {System.out.println(\"alt 1\");}\n" +
|
||||
" | {$i==2}? ID {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "a b", true);
|
||||
assertEquals("alt 2\nalt 1\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testPredicateDependentOnArg2() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"@members {int i = 0;}\n" +
|
||||
"s : a[2] a[1];\n" +
|
||||
"a[int i]\n" +
|
||||
" : {$i==1}? ID \n" +
|
||||
" | {$i==2}? ID \n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "a b", true);
|
||||
assertEquals("", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testDependentPredNotInOuterCtxShouldBeIgnored() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : b[2] ';' | b[2] '.' ; // decision in s drills down to ctx-dependent pred in a;\n" +
|
||||
"b[int i] : a[i] ;\n" +
|
||||
"a[int i]\n" +
|
||||
" : {$i==1}? ID {System.out.println(\"alt 1\");}\n" +
|
||||
" | {$i==2}? ID {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "a;", true);
|
||||
assertEquals("alt 2\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testIndependentPredNotPassedOuterCtxToAvoidCastException() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"s : b ';' | b '.' ;\n" +
|
||||
"b : a ;\n" +
|
||||
"a\n" +
|
||||
" : {false}? ID {System.out.println(\"alt 1\");}\n" +
|
||||
" | {true}? ID {System.out.println(\"alt 2\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "a;", true);
|
||||
assertEquals("alt 2\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testPredsInGlobalFOLLOW() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"@members {\n" +
|
||||
"boolean pred(boolean v) {\n" +
|
||||
" System.out.println(\"eval=\"+v);\n" +
|
||||
" return v;\n" +
|
||||
"}\n" +
|
||||
"}\n" +
|
||||
"s : e {this.pred(true)}? {System.out.println(\"parse\");} '!' ;\n" +
|
||||
"t : e {this.pred(false)}? ID ;\n" +
|
||||
"e : ID | ; // non-LL(1) so we use ATN\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "a!", true);
|
||||
assertEquals("eval=true\nparse\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testDepedentPredsInGlobalFOLLOW() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"@members {\n" +
|
||||
"boolean pred(boolean v) {\n" +
|
||||
" System.out.println(\"eval=\"+v);\n" +
|
||||
" return v;\n" +
|
||||
"}\n" +
|
||||
"}\n" +
|
||||
"s : a[99] ;\n" +
|
||||
"a[int i] : e {this.pred($i==99)}? {System.out.println(\"parse\");} '!' ;\n" +
|
||||
"b[int i] : e {this.pred($i==99)}? ID ;\n" +
|
||||
"e : ID | ; // non-LL(1) so we use ATN\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "a!", true);
|
||||
assertEquals("eval=true\nparse\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testActionsHidePredsInGlobalFOLLOW() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"@members {\n" +
|
||||
"boolean pred(boolean v) {\n" +
|
||||
" System.out.println(\"eval=\"+v);\n" +
|
||||
" return v;\n" +
|
||||
"}\n" +
|
||||
"}\n" +
|
||||
"s : e {} {this.pred(true)}? {System.out.println(\"parse\");} '!' ;\n" +
|
||||
"t : e {} {this.pred(false)}? ID ;\n" +
|
||||
"e : ID | ; // non-LL(1) so we use ATN\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') -> skip ;";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", "a!", true);
|
||||
assertEquals("eval=true\nparse\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
String testPredTestedEvenWhenUnAmbig(String input) throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"@members {boolean enumKeyword = true;}\n" +
|
||||
"primary\n" +
|
||||
" : ID {System.out.println(\"ID \"+$ID.text);}\n" +
|
||||
" | {!this.enumKeyword}? 'enum' {System.out.println(\"enum\");}\n" +
|
||||
" ;\n" +
|
||||
"ID : [a-z]+ ;\n" +
|
||||
"WS : [ \\t\\n\\r]+ -> skip ;";
|
||||
return execParser("T.g4", grammar, "TParser", "TLexer", "primary", input, true);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testPredTestedEvenWhenUnAmbig_1() throws Exception {
|
||||
String found = testPredTestedEvenWhenUnAmbig("abc");
|
||||
assertEquals("ID abc\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testPredTestedEvenWhenUnAmbig_2() throws Exception {
|
||||
String found = testPredTestedEvenWhenUnAmbig("enum");
|
||||
assertEquals("", found);
|
||||
assertEquals("line 1:0 no viable alternative at input 'enum'\n", this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testDisabledAlternative() throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"cppCompilationUnit : content+ EOF;\n" +
|
||||
"content: anything | {false}? .;\n" +
|
||||
"anything: ANY_CHAR;\n" +
|
||||
"ANY_CHAR: [_a-zA-Z0-9];";
|
||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "cppCompilationUnit", "hello", true);
|
||||
assertEquals("", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
String testPredFromAltTestedInLoopBack(String input) throws Exception {
|
||||
String grammar = "grammar T;\n" +
|
||||
"file_\n" +
|
||||
"@after {System.out.println($ctx.toStringTree(this));}\n" +
|
||||
" : para para EOF ;\n" +
|
||||
"para: paraContent NL NL ;\n" +
|
||||
"paraContent : ('s'|'x'|{this._input.LA(2)!=NL}? NL)+ ;\n" +
|
||||
"NL : '\\n' ;\n" +
|
||||
"s : 's' ;\n" +
|
||||
"X : 'x' ;";
|
||||
return execParser("T.g4", grammar, "TParser", "TLexer", "file_", input, true);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testPredFromAltTestedInLoopBack_1() throws Exception {
|
||||
String found = testPredFromAltTestedInLoopBack("s\n\n\nx\n");
|
||||
assertEquals("(file_ (para (paraContent s) \\n \\n) (para (paraContent \\n x \\n)) <EOF>)\n", found);
|
||||
assertEquals("line 5:0 mismatched input '<EOF>' expecting '\n'\n", this.stderrDuringParse);
|
||||
}
|
||||
|
||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
||||
@Test
|
||||
public void testPredFromAltTestedInLoopBack_2() throws Exception {
|
||||
String found = testPredFromAltTestedInLoopBack("s\n\n\nx\n\n");
|
||||
assertEquals("(file_ (para (paraContent s) \\n \\n) (para (paraContent \\n x) \\n \\n) <EOF>)\n", found);
|
||||
assertNull(this.stderrDuringParse);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -98,7 +98,7 @@ public void test<test.name>() throws Exception {
|
|||
<test.AfterGrammar>
|
||||
<endif>
|
||||
String input =<writeStringLiteral(test.Input)>;
|
||||
String found = execParser("<grammar>.g4", grammar, "<grammar>Parser", "<grammar>Lexer", "<test.Rule>", input, <writeBoolean(test.Debug)>);
|
||||
String found = execParser("<grammar>.g4", grammar, "<grammar>Parser", "<grammar>Lexer", "<test.Rule>", input, <writeBoolean(test.Options.("Debug"))>);
|
||||
assertEquals(<writeStringLiteral(test.Output)>, found);
|
||||
<if(!isEmpty.(test.Errors))>
|
||||
assertEquals(<writeStringLiteral(test.Errors)>, this.stderrDuringParse);
|
||||
|
|
Loading…
Reference in New Issue