Merge branch 'test-generation' into master

This commit is contained in:
Sam Harwell 2015-06-06 18:04:30 -05:00
commit 4455d526fe
43 changed files with 179 additions and 115 deletions

View File

@ -21,12 +21,12 @@ Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
lexer grammar <grammarName>;
import <slaveGrammarName>;
A : 'a' B {<writeln("\"M.A\"")>};
A : 'a' B {<writeln("\"M.A\"")>} ;
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
lexer grammar <grammarName>;
A : 'a' {<writeln("\"S.A\"")>};
B : 'b' {<writeln("\"S.B\"")>};
A : 'a' {<writeln("\"S.A\"")>} ;
B : 'b' {<writeln("\"S.B\"")>} ;
>>

View File

@ -60,7 +60,7 @@ x : A {<writeln("\"S.x\"")>};
>>
slaveGrammarT(grammarName) ::= <<
parser grammar S;
parser grammar T;
tokens { C, B, A } // reverse order
y : A {<writeln("\"T.y\"")>};
>>

View File

@ -21,13 +21,13 @@ Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M; // uses no rules from the import
import S;
s : 'b'{<Invoke_foo()>}; // gS is import pointer
s : 'b' {<Invoke_foo()>} ; // gS is import pointer
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
@members {
@parser::members {
<Declare_foo()>
}
a : B;

View File

@ -28,5 +28,5 @@ WS : (' '|'\n') -> skip ;
slaveGrammar(grammarName) ::= <<
parser grammar S;
a[int x] returns [int y] : B {<write("\"S.a\"")>;$y=1000;};
a[int x] returns [int y] : B {<write("\"S.a\"")> $y=1000;} ;
>>

View File

@ -28,5 +28,5 @@ WS : (' '|'\n') -> skip ;
slaveGrammar(grammarName) ::= <<
parser grammar S;
a : B {<write("\"S.a\"")>};
a : B {<write("\"S.a\"")>} ;
>>

View File

@ -29,11 +29,11 @@ WS : (' '|'\n') -> skip ;
slaveGrammarS(grammarName) ::= <<
parser grammar S;
a : B {<writeln("\"S.a\"")>};
a : b {<writeln("\"S.a\"")>};
b : B;
>>
slaveGrammarT(grammarName) ::= <<
parser grammar T;
a : B {<writeln("\"T.a\"")>};
a : B {<writeln("\"T.a\"")>};<! hidden by S.a !>
>>

View File

@ -34,7 +34,7 @@ b : 'b' ;
>>
slaveGrammarT(grammarName) ::= <<
parser grammar S;
parser grammar T;
tokens { A }
b : 'b' {<writeln("\"T.b\"")>};
>>

View File

@ -13,16 +13,17 @@ Rule() ::= "prog"
Input() ::= "float x = 3;"
Output() ::= <<
Decl: floatx=3;<\n>
JavaDecl: floatx=3;<\n>
>>
Errors() ::= ""
// for float to work in decl, type must be overridden
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
prog : decl ;
type_ : 'int' | 'float' ;
type : 'int' | 'float' ;
ID : 'a'..'z'+ ;
INT : '0'..'9'+ ;
WS : (' '|'\n') -> skip;
@ -30,8 +31,8 @@ WS : (' '|'\n') -> skip;
slaveGrammar(grammarName) ::= <<
parser grammar S;
type_ : 'int' ;
decl : type_ ID ';'
| type_ ID init ';' {<write("\"Decl: \" + $text")>};
type : 'int' ;
decl : type ID ';'
| type ID init ';' {<write("\"JavaDecl: \" + $text")>};
init : '=' INT;
>>

View File

@ -1,11 +1,17 @@
/*
* This is a regression test for antlr/antlr4#248 "Including grammar with only
* fragments breaks generated lexer".
* https://github.com/antlr/antlr4/issues/248
*/
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
"Test": {<masterGrammar("Test", "Unicode")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
"Unicode": {<slaveGrammar("Unicode")>}
]
Rule() ::= "program"
@ -18,17 +24,22 @@ Output() ::= <<
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
grammar <grammarName>;
import <slaveGrammarName; separator=", ">;
program : 'test' 'test';
WS : (UNICODE_CLASS_Zs)+ -> skip;
>>
slaveGrammar(grammarName) ::= <<
lexer grammar S;
lexer grammar <grammarName>;
fragment
UNICODE_CLASS_Zs : '\u0020' | '\u00A0' | '\u1680' | '\u180E'
| '\u2000'..'\u200A'
| '\u202F' | '\u205F' | '\u3000'
;
>>

View File

@ -20,13 +20,13 @@ Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
s : a;
B : 'b';
s : a ;
B : 'b' ;
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
options {}
a : B;
a : B ;
>>

View File

@ -25,7 +25,8 @@ B : 'b';
WS : (' '|'\n') -> skip ;
>>
// wasn't terminating. @after was injected into M as if it were @members
slaveGrammar(grammarName) ::= <<
parser grammar S;
a @after {} : B;
a @after {int x;} : B;
>>

View File

@ -1,3 +1,7 @@
// rules in lexer are imported at END so rules in master override
// *and* get priority over imported rules. So importing ID doesn't
// mess up keywords in master grammar
TestType() ::= "CompositeParser"
Grammar ::= [

View File

@ -7,6 +7,13 @@ Decision 1:
s0-'else'->:s1^=>1<\n>
>>
// Technically, this input sequence is not ambiguous because else
// uniquely predicts going into the optional subrule. else cannot
// be matched by exiting stat since that would only match '}' or
// the start of a stat. But, we are using the theory that
// SLL(1)=LL(1) and so we are avoiding full context parsing
// by declaring all else clause parsing to be ambiguous.
Errors() ::= <<
line 1:19 reportAttemptingFullContext d=1 (stat), input='else'
line 1:19 reportContextSensitivity d=1 (stat), input='else'<\n>

View File

@ -1,3 +1,7 @@
/*
* Tests predictions for the following case involving closures.
* http://www.antlr.org/wiki/display/~admin/2011/12/29/Flaw+in+ANTLR+v3+LL(*)+analysis+algorithm
*/
TestType() ::= "Parser"
Options ::= [

View File

@ -1,7 +1,7 @@
TestType() ::= "Parser"
Options ::= [
"Debug": false
"Debug": true
]
Grammar ::= [

View File

@ -1,4 +1,4 @@
/**
/*
* This is a regression test for "Support direct calls to left-recursive
* rules".
* https://github.com/antlr/antlr4/issues/161

View File

@ -21,14 +21,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
@ -59,7 +59,7 @@ e : '(' e ')'
|'\<\<='
|'%=') e
;
type_: ID
type: ID
| ID '[' ']'
| 'int'
| 'int' '[' ']'

View File

@ -3,7 +3,7 @@ import "JavaExpressions.stg"
Input() ::= "new T[((n-1) * x) + 1]"
Output() ::= <<
(s (e new (type_ T) [ (e (e ( (e (e ( (e (e n) - (e 1)) )) * (e x)) )) + (e 1)) ]) \<EOF>)<\n>
(s (e new (type T) [ (e (e ( (e (e ( (e (e n) - (e 1)) )) * (e x)) )) + (e 1)) ]) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -3,7 +3,7 @@ import "JavaExpressions.stg"
Input() ::= "(T)x"
Output() ::= <<
(s (e ( (type_ T) ) (e x)) \<EOF>)<\n>
(s (e ( (type T) ) (e x)) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -3,7 +3,7 @@ import "JavaExpressions.stg"
Input() ::= "new A().b"
Output() ::= <<
(s (e (e new (type_ A) ( )) . b) \<EOF>)<\n>
(s (e (e new (type A) ( )) . b) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -3,7 +3,7 @@ import "JavaExpressions.stg"
Input() ::= "(T)t.f()"
Output() ::= <<
(s (e (e ( (type_ T) ) (e (e t) . f)) ( )) \<EOF>)<\n>
(s (e (e ( (type T) ) (e (e t) . f)) ( )) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -1,4 +1,4 @@
/**
/*
* This is a regression test for antlr/antlr4#625 "Duplicate action breaks
* operator precedence"
* https://github.com/antlr/antlr4/issues/625

View File

@ -1,4 +1,4 @@
/**
/*
* This is a regression test for antlr/antlr4#625 "Duplicate action breaks
* operator precedence"
* https://github.com/antlr/antlr4/issues/625

View File

@ -1,4 +1,4 @@
/**
/*
* 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".
@ -25,8 +25,8 @@ e returns [int v]
| 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 {<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
| 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'+ ;

View File

@ -1,10 +1,10 @@
/**
* This is a regression test for antlr/antlr4#677 "labels not working in
* grammar file".
/*
* 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>
* This test treats `,` and `>>` as part of a single compound operator (similar
* to a ternary operator).
*/
TestType() ::= "Parser"

View File

@ -1,9 +1,9 @@
/**
* This is a regression test for antlr/antlr4#677 "labels not working in
* grammar file".
/*
* 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>
* This test treats the `,` and `>>` operators separately.
*/
TestType() ::= "Parser"

View File

@ -1,6 +1,6 @@
/**
* This is a regression test for #239 "recoursive parser using implicit
* tokens ignore white space lexer rule".
/*
* This is a regression test for #239 "recoursive parser using implicit tokens
* ignore white space lexer rule".
* https://github.com/antlr/antlr4/issues/239
*/
@ -63,7 +63,7 @@ ID : LETTER ALPHANUM*;
NUMBER : DIGIT+ ('.' DIGIT+)? (('e'|'E')('+'|'-')? DIGIT+)?;
DATE : '\'' DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT (' ' DIGIT DIGIT ':' DIGIT DIGIT ':' DIGIT DIGIT ('.' DIGIT+)?)? '\'';
SQ_STRING : '\'' ('\'\'' | ~'\'')* '\'';
DQ_STRING : '\"' ('\\\"' | ~'\"')* '\"';
DQ_STRING : '"' ('\\\\"' | ~'"')* '"';
WS : [ \t\n\r]+ -> skip ;
COMMENTS : ('/*' .*? '*/' | '//' ~'\n'* '\n' ) -> skip;
>>

View File

@ -1,17 +1,21 @@
TestType() ::= "Lexer"
Options ::= [
"Ignore": "Currently unable to generate the required CRLF input sequence."
]
Grammar ::= [
"L": {<grammar("L")>}
]
Input() ::= "34<\n> 34"
Input() ::= "34<\u000D><\n> 34"
Output() ::= <<
I
I
[@0,0:1='34',\<1>,1:0]
[@1,4:5='34',\<1>,2:1]
[@2,6:5='\<EOF>',\<-1>,2:3]<\n>
[@1,5:6='34',\<1>,2:1]
[@2,7:6='\<EOF>',\<-1>,2:3]<\n>
>>
Errors() ::= ""

View File

@ -1,17 +1,21 @@
TestType() ::= "Lexer"
Options ::= [
"Ignore": "Currently unable to generate the required CRLF input sequence."
]
Grammar ::= [
"L": {<grammar("L")>}
]
Input() ::= "34<\n> 34"
Input() ::= "34<\u000D><\n> 34"
Output() ::= <<
I
I
[@0,0:1='34',\<1>,1:0]
[@1,4:5='34',\<1>,2:1]
[@2,6:5='\<EOF>',\<-1>,2:3]<\n>
[@1,5:6='34',\<1>,2:1]
[@2,7:6='\<EOF>',\<-1>,2:3]<\n>
>>
Errors() ::= ""

View File

@ -1,10 +1,14 @@
TestType() ::= "Lexer"
Options ::= [
"Ignore": "Currently unable to generate the required CRLF input sequence."
]
Grammar ::= [
"L": {<grammar("L")>}
]
Input() ::= "34<\n> 34 a2 abc <\n> "
Input() ::= "34<\u000D> 34 a2 abc <\n> "
Output() ::= <<
I
@ -12,10 +16,10 @@ I
ID
ID
[@0,0:1='34',\<1>,1:0]
[@1,4:5='34',\<1>,2:1]
[@2,7:8='a2',\<2>,2:4]
[@3,10:12='abc',\<2>,2:7]
[@4,18:17='\<EOF>',\<-1>,3:3]<\n>
[@1,4:5='34',\<1>,1:4]
[@2,7:8='a2',\<2>,1:7]
[@3,10:12='abc',\<2>,1:10]
[@4,18:17='\<EOF>',\<-1>,2:3]<\n>
>>
Errors() ::= ""

View File

@ -1,15 +1,19 @@
TestType() ::= "Lexer"
Options ::= [
"Ignore": "Currently unable to generate the required CRLF input sequence."
]
Grammar ::= [
"L": {<grammar("L")>}
]
Input() ::= "00<\n>"
Input() ::= "00<\u000D><\n>"
Output() ::= <<
I
[@0,0:1='00',\<1>,1:0]
[@1,3:2='\<EOF>',\<-1>,2:0]<\n>
[@1,4:3='\<EOF>',\<-1>,2:0]<\n>
>>
Errors() ::= ""

View File

@ -18,6 +18,6 @@ Errors() ::= ""
grammar(grammarName) ::= <<
lexer grammar <grammarName>;
A : ["\\ab]+ {<writeln("\"A\"")>} ;
A : ["\\\\ab]+ {<writeln("\"A\"")>} ;
WS : [ \n\t]+ -> skip ;
>>

View File

@ -6,6 +6,7 @@ Grammar ::= [
Input() ::= ""
// must get DONE EOF
Output() ::= <<
[@0,0:-1='\<EOF>',\<1>,1:0]
[@1,0:-1='\<EOF>',\<-1>,1:0]<\n>

View File

@ -1,3 +1,8 @@
/*
* This is a regression test for antlr/antlr4#76 "Serialized ATN strings
* should be split when longer than 2^16 bytes (class file limitation)"
* https://github.com/antlr/antlr4/issues/76
*/
TestType() ::= "Lexer"
Grammar ::= [

View File

@ -1,3 +1,8 @@
/*
* This is a regression test for antlr/antlr4#224: "Parentheses without
* quantifier in lexer rules have unclear effect".
* https://github.com/antlr/antlr4/issues/224
*/
TestType() ::= "Lexer"
Grammar ::= [

View File

@ -6,6 +6,7 @@ Grammar ::= [
"L": {<grammar("L")>}
]
// stuff on end of comment matches another rule
Input() ::= <<
/* ick */
/* /* */

View File

@ -6,6 +6,7 @@ Grammar ::= [
"L": {<grammar("L")>}
]
// stuff on end of comment doesn't match another rule
Input() ::= <<
/* ick */x
/* /* */x

View File

@ -6,6 +6,7 @@ Grammar ::= [
"L": {<grammar("L")>}
]
// stuff on end of comment matches another rule
Input() ::= <<
/* ick */
/* /* */

View File

@ -6,6 +6,7 @@ Grammar ::= [
"L": {<grammar("L")>}
]
// stuff on end of comment doesn't match another rule
Input() ::= <<
/* ick */x
/* /* */x

View File

@ -12,7 +12,7 @@ Output() ::= <<
[@0,0:1='34',\<2>,1:0]
[@1,3:5='-21',\<1>,1:3]
[@2,7:7='3',\<2>,1:7]
[@3,8:7='\<EOF>',\<-1>,1:8]<\n>
[@3,8:7='\<EOF>',\<-1>,1:8]<\n><! EOF has no length so range is 8:7 not 8:8 !>
>>
Errors() ::= ""

View File

@ -2,6 +2,8 @@
* This is a regression test for antlr/antlr4#687 "Empty zero-length tokens
* cannot have lexer commands" and antlr/antlr4#688 "Lexer cannot match
* zero-length tokens"
* https://github.com/antlr/antlr4/issues/687
* https://github.com/antlr/antlr4/issues/688
*/
TestType() ::= "Lexer"

View File

@ -2,6 +2,7 @@ TestFile(file) ::= <<
package org.antlr.v4.test.runtime.java;
import org.antlr.v4.test.tool.BaseTest;
import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.*;
@ -21,7 +22,7 @@ public class Test<file.name> extends BaseTest {
>>
LexerTestMethod(test) ::= <<
@Test
<testAnnotations(test)>
public void test<test.name>() throws Exception {
mkdir(tmpdir);
@ -52,8 +53,42 @@ CompositeLexerTestMethod(test) ::= <<
<LexerTestMethod(test)>
>>
ParserTestMethod(test) ::= <<
testAnnotations(test) ::= <%
@Test
<if(test.Options.("Ignore"))>
<\n>@Ignore(<writeStringLiteral(test.Options.("Ignore"))>)
<elseif(IgnoredTests.(({<file.name>.<test.name>})))>
<\n>@Ignore(<writeStringLiteral(IgnoredTests.(({<file.name>.<test.name>})))>)
<endif>
%>
writeBoolean(o) ::= "<if(o && !isEmpty.(o))>true<else>false<endif>"
buildStringLiteral(text, variable) ::= <<
StringBuilder <variable>Builder = new StringBuilder(<strlen.(text)>);
<lines.(text):{line|<variable>Builder.append("<escape.(line)>");}; separator="\n">
String <variable> = <variable>Builder.toString();
>>
writeStringLiteral(text) ::= <%
<if(isEmpty.(text))>
""
<else>
<writeLines(lines.(text))>
<endif>
%>
writeLines(textLines) ::= <%
<if(rest(textLines))>
<textLines:{line|
<\n> "<escape.(line)>}; separator="\" +">"
<else>
"<escape.(first(textLines))>"
<endif>
%>
ParserTestMethod(test) ::= <<
<testAnnotations(test)>
public void test<test.name>() throws Exception {
mkdir(tmpdir);
@ -83,12 +118,15 @@ public void test<test.name>() throws Exception {
>>
string(text) ::= <<
"<escape.(text)>"
>>
CompositeParserTestMethod(test) ::= <<
<ParserTestMethod(test)>
>>
AbstractParserTestMethod(test) ::= <<
/* this file and method are generated, any edit will be overwritten by the next generation */
String test<test.name>(String input) throws Exception {
String grammar = <test.grammar.lines:{ line | "<line>};separator="\\n\" +\n", wrap, anchor>";
return execParser("<test.grammar.grammarName>.g4", grammar, "<test.grammar.grammarName>Parser", "<test.grammar.grammarName>Lexer", "<test.startRule>", input, <test.debug>);
@ -97,8 +135,7 @@ String test<test.name>(String input) throws Exception {
>>
ConcreteParserTestMethod(test) ::= <<
/* this file and method are generated, any edit will be overwritten by the next generation */
@Test
<testAnnotations(test)>
public void test<test.name>() throws Exception {
String found = test<test.baseName>("<test.input>");
assertEquals("<test.expectedOutput>", found);
@ -111,35 +148,6 @@ public void test<test.name>() throws Exception {
>>
string(text) ::= <<
"<escape.(text)>"
>>
writeBoolean(o) ::= "<if(o && !isEmpty.(o))>true<else>false<endif>"
buildStringLiteral(text, variable) ::= <<
StringBuilder <variable>Builder = new StringBuilder(<strlen.(text)>);
<lines.(text):{line|<variable>Builder.append("<escape.(line)>");}; separator="\n">
String <variable> = <variable>Builder.toString();
>>
writeStringLiteral(text) ::= <%
<if(isEmpty.(text))>
""
<else>
<writeLines(lines.(text))>
<endif>
%>
writeLines(textLines) ::= <%
<if(rest(textLines))>
<textLines:{line|
<\n> "<escape.(line)>}; separator="\" +">"
<else>
"<escape.(first(textLines))>"
<endif>
%>
writeln(s) ::= <<System.out.println(<s>);>>
write(s) ::= <<System.out.print(<s>);>>
@ -220,14 +228,6 @@ RuleInvocationStack() ::= "getRuleInvocationStack()"
LL_EXACT_AMBIG_DETECTION() ::= <<_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);>>
ParserPropertyMember() ::= <<
@members {
boolean Property() {
return true;
}
}
>>
PositionAdjustingLexer() ::= <<
@Override
@ -381,9 +381,11 @@ void foo() {
}
>>
Declare_foo() ::= <<public void foo() {System.out.println("foo");}>>
Declare_foo() ::= <<
public void foo() {System.out.println("foo");}
>>
Invoke_foo() ::= "this.foo();"
Invoke_foo() ::= "foo();"
Declare_pred() ::= <<boolean pred(boolean v) {
System.out.println("eval="+v);
@ -393,6 +395,10 @@ Declare_pred() ::= <<boolean pred(boolean v) {
Invoke_pred(v) ::= <<this.pred(<v>)>>
IgnoredTests ::= [
default: false
]
isEmpty ::= [
"": true,
default: false

View File

@ -149,8 +149,6 @@ public class TestCompositeGrammars extends BaseTest {
assertEquals(0, equeue.size());
}
@Test public void testImportedTokenVocabIgnoredWithWarning() throws Exception {
ErrorQueue equeue = new ErrorQueue();
String slave =
@ -404,7 +402,6 @@ public class TestCompositeGrammars extends BaseTest {
assertEquals(expecting, equeue.errors.size());
}
/**
* This is a regression test for antlr/antlr4#670 "exception when importing
* grammar". I think this one always worked but I found that a different