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.Ignore;
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.junit.Test;
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic class TestAutoAST extends BaseTest {
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected boolean debug = false;
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenList() throws Exception {
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT ;\n" +
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "abc 34", debug);
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc 34\n", found);
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenListInSingleAltBlock() throws Exception {
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : (ID INT) ;\n" +
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "abc 34", debug);
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc 34\n", found);
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testSimpleRootAtOuterLevel() throws Exception {
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID^ INT ;\n" +
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "abc 34", debug);
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(abc 34)\n", found);
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testSimpleRootAtOuterLevelReverse() throws Exception {
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : INT ID^ ;\n" +
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "34 abc", debug);
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(abc 34)\n", found);
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testBang() throws Exception {
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT! ID! INT ;\n" +
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "abc 34 dag 4532", debug);
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc 4532\n", found);
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testOptionalThenRoot() throws Exception {
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ( ID INT )? ID^ ;\n" +
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a 1 b", debug);
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(b a 1)\n", found);
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testLabeledStringRoot() throws Exception {
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : v='void'^ ID ';' ;\n" +
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "void foo;", debug);
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(void foo ;)\n", found);
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testWildcard() throws Exception {
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : v='void'^ . ';' ;\n" +
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "void foo;", debug);
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(void foo ;)\n", found);
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testWildcardRoot() throws Exception {
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : v='void' .^ ';' ;\n" +
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "void foo;", debug);
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(foo void ;)\n", found);
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testWildcardRootWithLabel() throws Exception {
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : v='void' x=.^ ';' ;\n" +
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "void foo;", debug);
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(foo void ;)\n", found);
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testWildcardRootWithListLabel() throws Exception {
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String grammar =
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "grammar T;\n" +
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "options {output=AST;}\n" +
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : v='void' x=.^ ';' ;\n" +
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+ ;\n" +
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "INT : '0'..'9'+;\n" +
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String found = execParser("T.g", grammar, "TParser", "TLexer",
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                  "a", "void foo;", debug);
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals("(foo void ;)\n", found);
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testWildcardBangWithListLabel() throws Exception {
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String grammar =
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "grammar T;\n" +
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "options {output=AST;}\n" +
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : v='void' x=.! ';' ;\n" +
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+ ;\n" +
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "INT : '0'..'9'+;\n" +
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String found = execParser("T.g", grammar, "TParser", "TLexer",
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                  "a", "void foo;", debug);
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals("void ;\n", found);
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRootRoot() throws Exception {
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID^ INT^ ID ;\n" +
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a 34 c", debug);
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(34 a c)\n", found);
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRootRoot2() throws Exception {
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT^ ID^ ;\n" +
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a 34 c", debug);
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(c (34 a))\n", found);
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRootThenRootInLoop() throws Exception {
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID^ (INT '*'^ ID)+ ;\n" +
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID  : 'a'..'z'+ ;\n" +
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a 34 * b 9 * c", debug);
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(* (* (a 34) b 9) c)\n", found);
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNestedSubrule() throws Exception {
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : 'void' (({;}ID|INT) ID | 'null' ) ';' ;\n" +
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "void a b;", debug);
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("void a b ;\n", found);
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testInvokeRule() throws Exception {
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a  : type ID ;\n" +
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"type : {;}'int' | 'float' ;\n" +
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "int a", debug);
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("int a\n", found);
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testInvokeRuleAsRoot() throws Exception {
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a  : type^ ID ;\n" +
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"type : {;}'int' | 'float' ;\n" +
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "int a", debug);
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(int a)\n", found);
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testInvokeRuleAsRootWithLabel() throws Exception {
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a  : x=type^ ID ;\n" +
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"type : {;}'int' | 'float' ;\n" +
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "int a", debug);
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(int a)\n", found);
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testInvokeRuleAsRootWithListLabel() throws Exception {
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a  : x+=type^ ID ;\n" +
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"type : {;}'int' | 'float' ;\n" +
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "int a", debug);
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(int a)\n", found);
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRuleRootInLoop() throws Exception {
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID ('+'^ ID)* ;\n" +
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a+b+c+d", debug);
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(+ (+ (+ a b) c) d)\n", found);
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRuleInvocationRuleRootInLoop() throws Exception {
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID (op^ ID)* ;\n" +
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"op : {;}'+' | '-' ;\n" +
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a+b+c-d", debug);
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(- (+ (+ a b) c) d)\n", found);
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTailRecursion() throws Exception {
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"s : a ;\n" +
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : atom ('exp'^ a)? ;\n" +
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"atom : INT ;\n" +
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "s", "3 exp 4 exp 5", debug);
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(exp 3 (exp 4 5))\n", found);
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testSet() throws Exception {
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID|INT ;\n" +
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "abc", debug);
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc\n", found);
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testSetRoot() throws Exception {
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ('+' | '-')^ ID ;\n" +
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "+abc", debug);
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(+ abc)\n", found);
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Ignore
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // TODO: FAILS until I rebuild the antlr.g in v3
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    //
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void testSetRootWithLabel() throws Exception {
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : x=('+' | '-')^ ID ;\n" +
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "+abc", debug);
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(+ abc)\n", found);
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testSetAsRuleRootInLoop() throws Exception {
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID (('+'|'-')^ ID)* ;\n" +
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a+b-c", debug);
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(- (+ a b) c)\n", found);
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNotSet() throws Exception {
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ~ID '+' INT ;\n" +
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "34+2", debug);
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("34 + 2\n", found);
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNotSetWithLabel() throws Exception {
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : x=~ID '+' INT ;\n" +
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "34+2", debug);
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("34 + 2\n", found);
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNotSetWithListLabel() throws Exception {
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : x=~ID '+' INT ;\n" +
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "34+2", debug);
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("34 + 2\n", found);
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNotSetRoot() throws Exception {
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ~'+'^ INT ;\n" +
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "34 55", debug);
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(34 55)\n", found);
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNotSetRootWithLabel() throws Exception {
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ~'+'^ INT ;\n" +
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "34 55", debug);
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(34 55)\n", found);
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNotSetRootWithListLabel() throws Exception {
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ~'+'^ INT ;\n" +
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "34 55", debug);
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(34 55)\n", found);
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNotSetRuleRootInLoop() throws Exception {
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : INT (~INT^ INT)* ;\n" +
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"blort : '+' ;\n" +
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "3+4+5", debug);
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(+ (+ 3 4) 5)\n", found);
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenLabelReuse() throws Exception {
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// check for compilation problem due to multiple defines
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : id=ID id=ID {System.out.print(\"2nd id=\"+$id.text+';');} ;\n" +
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a b", debug);
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("2nd id=b;a b\n", found);
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenLabelReuse2() throws Exception {
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// check for compilation problem due to multiple defines
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : id=ID id=ID^ {System.out.print(\"2nd id=\"+$id.text+';');} ;\n" +
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a b", debug);
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("2nd id=b;(b a)\n", found);
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenListLabelReuse() throws Exception {
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// check for compilation problem due to multiple defines
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// make sure ids has both ID tokens
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ids+=ID ids+=ID {System.out.print(\"id list=\"+$ids+';');} ;\n" +
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a b", debug);
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "id list=[[@0,0:0='a',<4>,1:0], [@2,2:2='b',<4>,1:2]];a b\n";
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, found);
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenListLabelReuse2() throws Exception {
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// check for compilation problem due to multiple defines
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// make sure ids has both ID tokens
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ids+=ID^ ids+=ID {System.out.print(\"id list=\"+$ids+';');} ;\n" +
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a b", debug);
546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "id list=[[@0,0:0='a',<4>,1:0], [@2,2:2='b',<4>,1:2]];(a b)\n";
547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, found);
548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenListLabelRuleRoot() throws Exception {
551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : id+=ID^ ;\n" +
555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a", debug);
560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("a\n", found);
561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenListLabelBang() throws Exception {
564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : id+=ID! ;\n" +
568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a", debug);
573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("", found);
574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRuleListLabel() throws Exception {
577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : x+=b x+=b {" +
581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"Tree t=(Tree)$x.get(1);" +
582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"System.out.print(\"2nd x=\"+t.toStringTree()+';');} ;\n" +
583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID;\n" +
584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a b", debug);
589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("2nd x=b;a b\n", found);
590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRuleListLabelRuleRoot() throws Exception {
593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ( x+=b^ )+ {" +
597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"System.out.print(\"x=\"+((CommonTree)$x.get(1)).toStringTree()+';');} ;\n" +
598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID;\n" +
599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a b", debug);
604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("x=(b a);(b a)\n", found);
605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRuleListLabelBang() throws Exception {
608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : x+=b! x+=b {" +
612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"System.out.print(\"1st x=\"+((CommonTree)$x.get(0)).toStringTree()+';');} ;\n" +
613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID;\n" +
614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a b", debug);
619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("1st x=a;b\n", found);
620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testComplicatedMelange() throws Exception {
623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// check for compilation problem
624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : A b=B b=B c+=C c+=C D {String s = $D.text;} ;\n" +
628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a' ;\n" +
629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b' ;\n" +
630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c' ;\n" +
631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"D : 'd' ;\n" +
632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "a b b c c d", debug);
635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("a b b c c d\n", found);
636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReturnValueWithAST() throws Exception {
639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID b {System.out.println($b.i);} ;\n" +
643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b returns [int i] : INT {$i=Integer.parseInt($INT.text);} ;\n" +
644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "abc 34", debug);
649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("34\nabc 34\n", found);
650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testSetLoop() throws Exception {
653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options { output=AST; }\n" +
656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"r : (INT|ID)+ ; \n" +
657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z' + ;\n" +
658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9' +;\n" +
659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS: (' ' | '\\n' | '\\t')+ {$channel = HIDDEN;};\n";
660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "r", "abc 34 d", debug);
662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc 34 d\n", found);
663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testExtraTokenInSimpleDecl() throws Exception {
666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"decl : type^ ID '='! INT ';'! ;\n" +
670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"type : 'int' | 'float' ;\n" +
671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "decl", "int 34 x=1;", debug);
676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("line 1:4 extraneous input '34' expecting ID\n", this.stderrDuringParse);
677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(int x 1)\n", found); // tree gets correct x and 1 tokens
678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testMissingIDInSimpleDecl() throws Exception {
681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tokens {EXPR;}\n" +
685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"decl : type^ ID '='! INT ';'! ;\n" +
686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"type : 'int' | 'float' ;\n" +
687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "decl", "int =1;", debug);
692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("line 1:4 missing ID at '='\n", this.stderrDuringParse);
693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(int <missing ID> 1)\n", found); // tree gets invented ID token
694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testMissingSetInSimpleDecl() throws Exception {
697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tokens {EXPR;}\n" +
701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"decl : type^ ID '='! INT ';'! ;\n" +
702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"type : 'int' | 'float' ;\n" +
703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "decl", "x=1;", debug);
708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("line 1:0 mismatched input 'x' expecting set null\n", this.stderrDuringParse);
709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(<error: x> x 1)\n", found); // tree gets invented ID token
710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testMissingTokenGivesErrorNode() throws Exception {
713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT ;\n" + // follow is EOF
717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "abc", debug);
722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("line 1:3 missing INT at '<EOF>'\n", this.stderrDuringParse);
723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc <missing INT>\n", found);
724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testMissingTokenGivesErrorNodeInInvokedRule() throws Exception {
727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b ;\n" +
731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID INT ;\n" + // follow should see EOF
732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "abc", debug);
737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("line 1:3 mismatched input '<EOF>' expecting INT\n", this.stderrDuringParse);
738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("<mismatched token: [@1,3:3='<EOF>',<-1>,1:3], resync=abc>\n", found);
739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testExtraTokenGivesErrorNode() throws Exception {
742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b c ;\n" +
746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID ;\n" +
747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"c : INT ;\n" +
748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "abc ick 34", debug);
753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("line 1:4 extraneous input 'ick' expecting INT\n", this.stderrDuringParse);
754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc 34\n", found);
755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testMissingFirstTokenGivesErrorNode() throws Exception {
758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT ;\n" +
762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "34", debug);
767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("line 1:0 missing ID at '34'\n", this.stderrDuringParse);
768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("<missing ID> 34\n", found);
769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testMissingFirstTokenGivesErrorNode2() throws Exception {
772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b c ;\n" +
776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID ;\n" +
777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"c : INT ;\n" +
778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "34", debug);
783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// finds an error at the first token, 34, and re-syncs.
784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// re-synchronizing does not consume a token because 34 follows
785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// ref to rule b (start of c). It then matches 34 in c.
786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("line 1:0 missing ID at '34'\n", this.stderrDuringParse);
787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("<missing ID> 34\n", found);
788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNoViableAltGivesErrorNode() throws Exception {
791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar foo;\n" +
793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | c ;\n" +
795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : ID ;\n" +
796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"c : INT ;\n" +
797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"S : '*' ;\n" +
799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("foo.g", grammar, "fooParser", "fooLexer",
802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  "a", "*", debug);
803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("line 1:0 no viable alternative at input '*'\n", this.stderrDuringParse);
804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("<unexpected: [@0,0:0='*',<6>,1:0], resync=*>\n", found);
805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// S U P P O R T
809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void _test() throws Exception {
811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a :  ;\n" +
815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer", "a", "abc 34", debug);
819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("\n", found);
820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
823