1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/*
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD license"]
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  Copyright (c) 2010 Terence Parr
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  All rights reserved.
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  Redistribution and use in source and binary forms, with or without
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  modification, are permitted provided that the following conditions
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  are met:
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  1. Redistributions of source code must retain the above copyright
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      notice, this list of conditions and the following disclaimer.
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2. Redistributions in binary form must reproduce the above copyright
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      notice, this list of conditions and the following disclaimer in the
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      documentation and/or other materials provided with the distribution.
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  3. The name of the author may not be used to endorse or promote products
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      derived from this software without specific prior written permission.
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpackage org.antlr.test;
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.junit.Test;
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic class TestTreeParsing extends BaseTest {
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testFlatList() throws Exception {
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT;\n" +
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT\n" +
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"    {System.out.println($ID+\", \"+$INT);}\n" +
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc, 34\n", found);
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testSimpleTree() throws Exception {
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT -> ^(ID INT);\n" +
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ^(ID INT)\n" +
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"    {System.out.println($ID+\", \"+$INT);}\n" +
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc, 34\n", found);
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testFlatVsTreeDecision() throws Exception {
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b c ;\n" +
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID INT -> ^(ID INT);\n" +
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"c : ID INT;\n" +
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b b ;\n" +
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID INT    {System.out.print($ID+\" \"+$INT);}\n" +
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  | ^(ID INT) {System.out.print(\"^(\"+$ID+\" \"+$INT+')');}\n" +
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "a 1 b 2");
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("^(a 1)b 2\n", found);
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testFlatVsTreeDecision2() throws Exception {
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b c ;\n" +
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID INT+ -> ^(ID INT+);\n" +
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"c : ID INT+;\n" +
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b b ;\n" +
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID INT+    {System.out.print($ID+\" \"+$INT);}\n" +
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  | ^(x=ID (y=INT)+) {System.out.print(\"^(\"+$x+' '+$y+')');}\n" +
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a",
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a 1 2 3 b 4 5");
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("^(a 3)b 5\n", found);
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testCyclicDFALookahead() throws Exception {
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT+ PERIOD;\n" +
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"SEMI : ';' ;\n"+
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"PERIOD : '.' ;\n"+
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT+ PERIOD {System.out.print(\"alt 1\");}"+
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  | ID INT+ SEMI   {System.out.print(\"alt 2\");}\n" +
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "a 1 2 3.");
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("alt 1\n", found);
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTemplateOutput() throws Exception {
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT;\n" +
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP;\n" +
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=template; ASTLabelType=CommonTree;}\n" +
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"s : a {System.out.println($a.st);};\n" +
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT -> {new StringTemplate($INT.text)}\n" +
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("34\n", found);
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNullableChildList() throws Exception {
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT? -> ^(ID INT?);\n" +
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ^(ID INT?)\n" +
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"    {System.out.println($ID);}\n" +
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc");
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc\n", found);
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNullableChildList2() throws Exception {
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT? SEMI -> ^(ID INT?) SEMI ;\n" +
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"SEMI : ';' ;\n"+
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ^(ID INT?) SEMI\n" +
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"    {System.out.println($ID);}\n" +
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc;");
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc\n", found);
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNullableChildList3() throws Exception {
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : x=ID INT? (y=ID)? SEMI -> ^($x INT? $y?) SEMI ;\n" +
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"SEMI : ';' ;\n"+
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ^(ID INT? b) SEMI\n" +
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"    {System.out.println($ID+\", \"+$b.text);}\n" +
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n"+
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID? ;\n";
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc def;");
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc, def\n", found);
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testActionsAfterRoot() throws Exception {
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : x=ID INT? SEMI -> ^($x INT?) ;\n" +
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"SEMI : ';' ;\n"+
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a @init {int x=0;} : ^(ID {x=1;} {x=2;} INT?)\n" +
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"    {System.out.println($ID+\", \"+x);}\n" +
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc;");
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc, 2\n", found);
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testWildcardLookahead() throws Exception {
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String grammar =
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "grammar T;\n" +
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "options {output=AST;}\n" +
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : ID '+'^ INT;\n" +
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+ ;\n" +
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "INT : '0'..'9'+;\n" +
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "SEMI : ';' ;\n"+
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "PERIOD : '.' ;\n"+
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String treeGrammar =
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" +
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : ^('+' . INT) {System.out.print(\"alt 1\");}"+
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  ;\n";
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    treeGrammar, "TP", "TLexer", "a", "a", "a + 2");
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals("alt 1\n", found);
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testWildcardLookahead2() throws Exception {
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String grammar =
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "grammar T;\n" +
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "options {output=AST;}\n" +
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : ID '+'^ INT;\n" +
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+ ;\n" +
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "INT : '0'..'9'+;\n" +
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "SEMI : ';' ;\n"+
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "PERIOD : '.' ;\n"+
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String treeGrammar =
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" +
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : ^('+' . INT) {System.out.print(\"alt 1\");}"+
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  | ^('+' . .)   {System.out.print(\"alt 2\");}\n" +
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  ;\n";
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // AMBIG upon '+' DOWN INT UP etc.. but so what.
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    treeGrammar, "TP", "TLexer", "a", "a", "a + 2");
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals("alt 1\n", found);
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testWildcardLookahead3() throws Exception {
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String grammar =
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "grammar T;\n" +
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "options {output=AST;}\n" +
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : ID '+'^ INT;\n" +
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+ ;\n" +
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "INT : '0'..'9'+;\n" +
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "SEMI : ';' ;\n"+
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "PERIOD : '.' ;\n"+
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String treeGrammar =
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" +
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : ^('+' ID INT) {System.out.print(\"alt 1\");}"+
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  | ^('+' . .)   {System.out.print(\"alt 2\");}\n" +
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  ;\n";
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // AMBIG upon '+' DOWN INT UP etc.. but so what.
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    treeGrammar, "TP", "TLexer", "a", "a", "a + 2");
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals("alt 1\n", found);
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testWildcardPlusLookahead() throws Exception {
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String grammar =
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "grammar T;\n" +
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "options {output=AST;}\n" +
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : ID '+'^ INT;\n" +
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+ ;\n" +
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "INT : '0'..'9'+;\n" +
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "SEMI : ';' ;\n"+
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "PERIOD : '.' ;\n"+
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String treeGrammar =
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" +
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : ^('+' INT INT ) {System.out.print(\"alt 1\");}"+
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  | ^('+' .+)   {System.out.print(\"alt 2\");}\n" +
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  ;\n";
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // AMBIG upon '+' DOWN INT UP etc.. but so what.
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    treeGrammar, "TP", "TLexer", "a", "a", "a + 2");
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals("alt 2\n", found);
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
341