Tests generator and generated tests for Java

As of commit, the generator produces tests for Java, Python 2 and 3,
NodeJS and Safari.
It’s a great relief to seethe full set of runtime tests pas identically
on all targets
The previous tests are now located at org.antlr.v4.test.tool, the files
have been cleaned up to remove duplicates
This commit is contained in:
ericvergnaud 2014-11-01 01:47:19 +08:00
parent 97a2946a2d
commit 86fc7fd44d
36 changed files with 88 additions and 72 deletions

View File

@ -34,9 +34,11 @@ public class Generator {
Map<String, File> configs = new HashMap<String, File>();
configs.put("Source", readGrammarDir()); // source of test templates
configs.put("Java", readJavaDir()); // generated Java tests
configs.put("Python2", readPython2Dir()); // generated Python2 tests
configs.put("Python3", readPython3Dir()); // generated Python3 tests
configs.put("NodeJS", readNodeJSDir()); // generated NodeJS tests
configs.put("Safari", readSafariDir()); // generated Firefox tests
configs.put("Firefox", readFirefoxDir()); // generated Firefox tests
// configs.put("Firefox", readFirefoxDir()); // generated Firefox tests
return configs;
}
@ -48,6 +50,16 @@ public class Generator {
return new File(new URI(uri));
}
private static File readPython2Dir() {
// TODO Auto-generated method stub
return new File("/Users/ericvergnaud/Development/antlr4/antlr/antlr4-python2/tool/test/org/antlr/v4/test/rt/py2");
}
private static File readPython3Dir() {
// TODO Auto-generated method stub
return new File("/Users/ericvergnaud/Development/antlr4/antlr/antlr4-python3/tool/test/org/antlr/v4/test/rt/py3");
}
private static File readNodeJSDir() {
// TODO Auto-generated method stub
return new File("/Users/ericvergnaud/Development/antlr4/antlr/antlr4-javascript/tool/test/org/antlr/v4/test/rt/js/node");
@ -802,12 +814,12 @@ public class Generator {
"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",
"(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");
"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>)\n",
"*a", "(s (declarator * (declarator a)) <EOF>)\n",

View File

@ -1,7 +1,5 @@
parser grammar S;
type_ : 'int' ;
decl : type_ ID ';'
| type_ ID init ';' {
<write("\"Decl: \" + $text")>
};
| type_ ID init ';' {<write("\"Decl: \" + $text")>};
init : '=' INT;

View File

@ -1,5 +1,5 @@
grammar M;
import S;
a : A {<writeln("\"M.a: \"+$A")>};
a : A {<Append("\"M.a: \"","$A"):writeln()>};
A : 'abc' {<writeln("\"M.A\"")>};
WS : (' '|'\n') -> skip ;

View File

@ -8,14 +8,14 @@ e : '(' e ')'
| 'super'
| INT
| ID
| type '.' 'class'
| type_ '.' 'class'
| e '.' ID
| e '.' 'this'
| e '.' 'super' '(' expressionList? ')'
| e '.' 'new' ID '(' expressionList? ')'
| 'new' type ( '(' expressionList? ')' | ('[' e ']')+)
| 'new' type_ ( '(' expressionList? ')' | ('[' e ']')+)
| e '[' e ']'
| '(' type ')' e
| '(' type_ ')' e
| e ('++' | '--')
| e '(' expressionList? ')'
| ('+'|'-'|'++'|'--') e
@ -46,7 +46,7 @@ e : '(' e ')'
|'\<\<='
|'%=') e
;
type: ID
type_: ID
| ID '[' ']'
| 'int'
| 'int' '[' ']'

View File

@ -1,7 +1,7 @@
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'>
e : a=e op=('*'|'/') b=e {}{<True()>}?
| a=e op=('+'|'-') b=e {}\<p=3>{<True()>}?\<fail='Message'>
| INT {}{}
| '(' x=e ')' {}{}
;

View File

@ -1,6 +1,6 @@
grammar <grammarName>;
s @after {<ToStringTree("$ctx"):writeln()>} : a ;
a : a {<true>}? ID
a : a {<True()>}? ID
| ID
;
ID : 'a'..'z'+ ;

View File

@ -1,6 +1,6 @@
grammar <grammarName>;
s @after {<ToStringTree("$ctx"):writeln()>} : a ;
a : a ID {false}?\<fail='custom message'>
a : a ID {<False()>}?\<fail='custom message'>
| ID
;
ID : 'a'..'z'+ ;

View File

@ -1,2 +1,2 @@
grammar <grammarName>;
a : 'a' x='b' {<writeln("\"conjured=\"+$x")>} 'c' ;
a : 'a' x='b' {<Append("\"conjured=\"","$x"):writeln()>} 'c' ;

View File

@ -1,2 +1,2 @@
grammar <grammarName>;
a : 'a' x=('b'|'c') {<writeln("\"conjured=\"+$x")>} 'd' ;
a : 'a' x=('b'|'c') {<Append("\"conjured=\"","$x"):writeln()>} 'd' ;

View File

@ -1,8 +1,8 @@
grammar <grammarName>;
start : a* EOF;
a
: label=subrule { <writeln("$label.text")> } #One
| label='y' { <writeln("$label.text")> } #Two
: label=subrule {<writeln("$label.text")>} #One
| label='y' {<writeln("$label.text")>} #Two
;
subrule : 'x';
WS : (' '|'\n') -> skip ;

View File

@ -1,5 +1,5 @@
grammar <grammarName>;
a : (ID|ATN)* ATN? {<writeln("$text")>} ;
a : (ID|ATN_)* ATN_? {<writeln("$text")>} ;
ID : 'a'..'z'+ ;
ATN : '0'..'9'+;
ATN_ : '0'..'9'+;
WS : (' '|'\n') -> skip ;

View File

@ -1,5 +1,5 @@
lexer grammar <grammarName>;
E1 : 'enum' { <false> }? ;
E2 : 'enum' { <true> }? ; // winner not E1 or ID
E1 : 'enum' { <False()> }? ;
E2 : 'enum' { <True()> }? ; // winner not E1 or ID
ID : 'a'..'z'+ ;
WS : (' '|'\n') -> skip;

View File

@ -1,4 +1,4 @@
lexer grammar <grammarName>;
ENUM : [a-z]+ { <false> }? ;
ENUM : [a-z]+ { <False()> }? ;
ID : [a-z]+ ;
WS : (' '|'\n') -> skip;

View File

@ -1,4 +1,4 @@
lexer grammar <grammarName>;
ENUM : 'enum' { <false> }? ;
ENUM : 'enum' { <False()> }? ;
ID : 'a'..'z'+ ;
WS : (' '|'\n') -> skip;

View File

@ -2,7 +2,7 @@ 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\"")>}
| {<False()>}? ID {<writeln("\"alt 3\"")>}
;
ID : 'a'..'z'+ ;
INT : '0'..'9'+;

View File

@ -3,7 +3,7 @@ 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\"")>}
| {<False()>}? ID {<writeln("\"alt 4\"")>}
;
ID : 'a'..'z'+ ;
INT : '0'..'9'+;

View File

@ -2,8 +2,8 @@ grammar <grammarName>;
@members {
<Declare_pred()>
}
s : e {} {<true:Invoke_pred()>}? {<writeln("\"parse\"")>} '!' ;
t : e {} {<false:Invoke_pred()>}? ID ;
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'+;

View File

@ -1,5 +1,5 @@
grammar <grammarName>;
cppCompilationUnit : content+ EOF;
content: anything | {<false>}? .;
content: anything | {<False()>}? .;
anything: ANY_CHAR;
ANY_CHAR: [_a-zA-Z0-9];

View File

@ -2,8 +2,8 @@ grammar <grammarName>;
s : b ';' | b '.' ;
b : a ;
a
: {<false>}? ID {<writeln("\"alt 1\"")>}
| {<true>}? ID {<writeln("\"alt 2\"")>}
: {<False()>}? ID {<writeln("\"alt 1\"")>}
| {<True()>}? ID {<writeln("\"alt 2\"")>}
;
ID : 'a'..'z'+ ;
INT : '0'..'9'+;

View File

@ -1,7 +1,7 @@
grammar <grammarName>;
s : a a;
a : {<false>}? ID INT {<writeln("\"alt 1\"")>}
| {<false>}? ID INT {<writeln("\"alt 2\"")>}
a : {<False()>}? ID INT {<writeln("\"alt 1\"")>}
| {<False()>}? ID INT {<writeln("\"alt 2\"")>}
;
ID : 'a'..'z'+ ;
INT : '0'..'9'+;

View File

@ -3,7 +3,7 @@ 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\"")>}
| {<True()>}? ID {<writeln("\"alt 2\"")>}
;
ID : 'a'..'z'+ ;
INT : '0'..'9'+;

View File

@ -1,8 +1,8 @@
grammar <grammarName>;
@members {<InitBooleanMember("enumKeyword",true)>}
@members {<InitBooleanMember("enumKeyword",True())>}
primary
: ID {<writeln("\"ID \"+$ID.text")>}
| {!<GetMember("enumKeyword")>}? 'enum' {<writeln("\"enum\"")>}
| {<GetMember("enumKeyword"):Not()>}? 'enum' {<writeln("\"enum\"")>}
;
ID : [a-z]+ ;
WS : [ \t\n\r]+ -> skip ;

View File

@ -2,8 +2,8 @@ grammar <grammarName>;
@members {
<Declare_pred()>
}
s : e {<true:Invoke_pred()>}? {<writeln("\"parse\"")>} '!' ;
t : e {<false:Invoke_pred()>}? ID ;
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'+;

View File

@ -1,7 +1,7 @@
grammar <grammarName>;
s : a a a; // do 3x: once in ATN, next in DFA then INT in ATN
a : {<false>}? ID {<writeln("\"alt 1\"")>}
| {<true>}? ID {<writeln("\"alt 2\"")>}
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
| {<True()>}? ID {<writeln("\"alt 2\"")>}
| INT {<writeln("\"alt 3\"")>}
;
ID : 'a'..'z'+ ;

View File

@ -1,7 +1,7 @@
grammar <grammarName>;
s : a ;
a : {<false>}? ID {<writeln("\"alt 1\"")>}
| {<true>}? INT {<writeln("\"alt 2\"")>}
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
| {<True()>}? INT {<writeln("\"alt 2\"")>}
;
ID : 'a'..'z'+ ;
INT : '0'..'9'+;

View File

@ -1,7 +1,7 @@
grammar <grammarName>;
s : a a a;
a : {<false>}? ID {<writeln("\"alt 1\"")>}
| {<true>}? INT {<writeln("\"alt 2\"")>}
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
| {<True()>}? INT {<writeln("\"alt 2\"")>}
;
ID : 'a'..'z'+ ;
INT : '0'..'9'+;

View File

@ -1,7 +1,7 @@
grammar <grammarName>;
s : a+ ;
a : {<false>}? ID {<writeln("\"alt 1\"")>}
| {<true>}? ID {<writeln("\"alt 2\"")>}
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
| {<True()>}? ID {<writeln("\"alt 2\"")>}
;
ID : 'a'..'z'+ ;
INT : '0'..'9'+;

View File

@ -1,7 +1,7 @@
grammar <grammarName>;
@members {<InitIntMember("i","0")>}
s : ({<AddMember("i","1")>
<PlusMember("\"i=\"","i"):writeln()>} a)+ ;
<PlusMember("\"i=\"","i"):writeln()>} a)+ ;
a : {<ModMemberEquals("i","2","0")>}? ID {<writeln("\"alt 1\"")>}
| {<ModMemberNotEquals("i","2","0")>}? ID {<writeln("\"alt 2\"")>}
;

View File

@ -2,7 +2,7 @@ grammar <grammarName>;
s : a {<writeln("\"alt 1\"")>}
| b {<writeln("\"alt 2\"")>}
;
a : {<false>}? ID INT
a : {<False()>}? ID INT
| ID INT
;
b : ID ID

View File

@ -3,8 +3,8 @@ s : a ';' a;
// ';' helps us to resynchronize without consuming
// 2nd 'a' reference. We our testing that the DFA also
// throws an exception if the validating predicate fails
a : {<false>}? ID {<writeln("\"alt 1\"")>}
| {<true>}? INT {<writeln("\"alt 2\"")>}
a : {<False()>}? ID {<writeln("\"alt 1\"")>}
| {<True()>}? INT {<writeln("\"alt 2\"")>}
;
ID : 'a'..'z'+ ;
INT : '0'..'9'+;

View File

@ -99,10 +99,18 @@ writeln(s) ::= <<System.out.println(<s>);>>
write(s) ::= <<System.out.print(<s>);>>
False() ::= "false"
True() ::= "true"
Not(v) ::= "!<v>"
Assert(s) ::= <<assert(<s>);>>
Cast(t,v) ::= "((<t>)<v>)"
Append(a,b) ::= "<a> + <b>"
Concat(a,b) ::= "<a><b>"
DeclareLocal(s,v) ::= "Object <s> = <v>;"

View File

@ -209,9 +209,7 @@ public class TestCompositeParsers extends BaseTest {
String slave_S = "parser grammar S;\n" +
"type_ : 'int' ;\n" +
"decl : type_ ID ';'\n" +
" | type_ ID init ';' {\n" +
" System.out.print(\"Decl: \" + $text);\n" +
" };\n" +
" | type_ ID init ';' {System.out.print(\"Decl: \" + $text);};\n" +
"init : '=' INT;";
mkdir(tmpdir);
writeFile(tmpdir, "S.g4", slave_S);
@ -261,7 +259,7 @@ public class TestCompositeParsers extends BaseTest {
String grammar = "grammar M;\n" +
"import S;\n" +
"a : A {System.out.println(\"M.a: \"+$A);};\n" +
"a : A {System.out.println(\"M.a: \" + $A);};\n" +
"A : 'abc' {System.out.println(\"M.A\");};\n" +
"WS : (' '|'\\n') -> skip ;";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "a", "abc", false);

View File

@ -236,14 +236,14 @@ public class TestLeftRecursion extends BaseTest {
" | 'super'\n" +
" | INT\n" +
" | ID\n" +
" | type '.' 'class'\n" +
" | type_ '.' 'class'\n" +
" | e '.' ID\n" +
" | e '.' 'this'\n" +
" | e '.' 'super' '(' expressionList? ')'\n" +
" | e '.' 'new' ID '(' expressionList? ')'\n" +
" | 'new' type ( '(' expressionList? ')' | ('[' e ']')+)\n" +
" | 'new' type_ ( '(' expressionList? ')' | ('[' e ']')+)\n" +
" | e '[' e ']'\n" +
" | '(' type ')' e\n" +
" | '(' type_ ')' e\n" +
" | e ('++' | '--')\n" +
" | e '(' expressionList? ')'\n" +
" | ('+'|'-'|'++'|'--') e\n" +
@ -274,7 +274,7 @@ public class TestLeftRecursion extends BaseTest {
" |'<<='\n" +
" |'%=') e\n" +
" ;\n" +
"type: ID \n" +
"type_: ID \n" +
" | ID '[' ']'\n" +
" | 'int'\n" +
" | 'int' '[' ']' \n" +
@ -330,21 +330,21 @@ public class TestLeftRecursion extends BaseTest {
@Test
public void testJavaExpressions_7() throws Exception {
String found = testJavaExpressions("(T)x");
assertEquals("(s (e ( (type T) ) (e x)) <EOF>)\n", 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>)\n", 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>)\n", found);
assertEquals("(s (e (e ( (type_ T) ) (e (e t) . f)) ( )) <EOF>)\n", found);
assertNull(this.stderrDuringParse);
}
@ -365,7 +365,7 @@ public class TestLeftRecursion extends BaseTest {
@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>)\n", 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);
}

View File

@ -44,7 +44,7 @@ public class TestParserErrors extends BaseTest {
@Test
public void testConjuringUpToken() throws Exception {
String grammar = "grammar T;\n" +
"a : 'a' x='b' {System.out.println(\"conjured=\"+$x);} 'c' ;";
"a : 'a' x='b' {System.out.println(\"conjured=\" + $x);} 'c' ;";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "ac", false);
assertEquals("conjured=[@-1,-1:-1='<missing 'b'>',<2>,1:1]\n", found);
assertEquals("line 1:1 missing 'b' at 'c'\n", this.stderrDuringParse);
@ -62,7 +62,7 @@ public class TestParserErrors extends BaseTest {
@Test
public void testConjuringUpTokenFromSet() throws Exception {
String grammar = "grammar T;\n" +
"a : 'a' x=('b'|'c') {System.out.println(\"conjured=\"+$x);} 'd' ;";
"a : 'a' x=('b'|'c') {System.out.println(\"conjured=\" + $x);} 'd' ;";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "ad", false);
assertEquals("conjured=[@-1,-1:-1='<missing 'b'>',<2>,1:1]\n", found);
assertEquals("line 1:1 missing {'b', 'c'} at 'd'\n", this.stderrDuringParse);

View File

@ -317,8 +317,8 @@ public class TestParserExec extends BaseTest {
String grammar = "grammar T;\n" +
"start : a* EOF;\n" +
"a\n" +
" : label=subrule { System.out.println($label.text); } #One\n" +
" | label='y' { System.out.println($label.text); } #Two\n" +
" : label=subrule {System.out.println($label.text);} #One\n" +
" | label='y' {System.out.println($label.text);} #Two\n" +
" ;\n" +
"subrule : 'x';\n" +
"WS : (' '|'\\n') -> skip ;";
@ -395,9 +395,9 @@ public class TestParserExec extends BaseTest {
String testReferenceToATN(String input) throws Exception {
String grammar = "grammar T;\n" +
"a : (ID|ATN)* ATN? {System.out.println($text);} ;\n" +
"a : (ID|ATN_)* ATN_? {System.out.println($text);} ;\n" +
"ID : 'a'..'z'+ ;\n" +
"ATN : '0'..'9'+;\n" +
"ATN_ : '0'..'9'+;\n" +
"WS : (' '|'\\n') -> skip ;";
return execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
}

View File

@ -216,7 +216,7 @@ public class TestSemPredEvalParser extends BaseTest {
String grammar = "grammar T;\n" +
"@members {int i = 0;}\n" +
"s : ({this.i += 1;\n" +
" System.out.println(\"i=\" + this.i);} a)+ ;\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" +