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 Gruver/** Test hetero trees in parsers and tree parsers */
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic class TestHeteroAST extends BaseTest {
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected boolean debug = false;
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// PARSERS -- AUTO AST
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testToken() throws Exception {
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String grammar =
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "grammar T;\n" +
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "options {output=AST;}\n" +
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "@members {static class V extends CommonTree {\n" +
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public V(Token t) { token=t;}\n" +
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public String toString() { return token.getText()+\"<V>\";}\n" +
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "}\n" +
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "}\n"+
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : ID<V> ;\n"+
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+ ;\n" +
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String found = execParser("T.g", grammar, "TParser", "TLexer",
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    "a", "a", debug);
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals("a<V>\n", found);
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenCommonTree() throws Exception {
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID<CommonTree> ;\n"+
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					"a", "a", debug);
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("a\n", found);
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testTokenWithQualifiedType() throws Exception {
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String grammar =
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "grammar T;\n" +
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "options {output=AST;}\n" +
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "@members {static class V extends CommonTree {\n" +
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public V(Token t) { token=t;}\n" +
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public String toString() { return token.getText()+\"<V>\";}\n" +
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "}\n" +
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "}\n"+
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : ID<TParser.V> ;\n"+ // TParser.V is qualified name
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+ ;\n" +
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String found = execParser("T.g", grammar, "TParser", "TLexer",
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    "a", "a", debug);
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals("a<V>\n", found);
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testNamedType() throws Exception {
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {static class V extends CommonTree {\n" +
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Token t) { token=t;}\n" +
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID<node=V> ;\n"+
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					"a", "a", debug);
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("a<V>\n", found);
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenWithLabel() throws Exception {
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {static class V extends CommonTree {\n" +
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Token t) { token=t;}\n" +
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : x=ID<V> ;\n"+
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "a", debug);
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("a<V>\n", found);
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenWithListLabel() throws Exception {
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {static class V extends CommonTree {\n" +
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Token t) { token=t;}\n" +
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : x+=ID<V> ;\n"+
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "a", debug);
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("a<V>\n", found);
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenRoot() throws Exception {
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {static class V extends CommonTree {\n" +
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Token t) { token=t;}\n" +
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID<V>^ ;\n"+
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "a", debug);
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("a<V>\n", found);
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTokenRootWithListLabel() throws Exception {
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {static class V extends CommonTree {\n" +
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Token t) { token=t;}\n" +
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : x+=ID<V>^ ;\n"+
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "a", debug);
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("a<V>\n", found);
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testString() throws Exception {
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {static class V extends CommonTree {\n" +
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Token t) { token=t;}\n" +
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : 'begin'<V> ;\n"+
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "begin", debug);
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("begin<V>\n", found);
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testStringRoot() throws Exception {
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {static class V extends CommonTree {\n" +
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Token t) { token=t;}\n" +
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : 'begin'<V>^ ;\n"+
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "begin", debug);
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("begin<V>\n", found);
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// PARSERS -- REWRITE AST
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRewriteToken() throws Exception {
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {static class V extends CommonTree {\n" +
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Token t) { token=t;}\n" +
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID -> ID<V> ;\n"+
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "a", debug);
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("a<V>\n", found);
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRewriteTokenWithArgs() throws Exception {
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// arg to ID<V>[42,19,30] means you're constructing node not associated with ID
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// so must pass in token manually
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {\n" +
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"static class V extends CommonTree {\n" +
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public int x,y,z;\n"+
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(int ttype, int x, int y, int z) { this.x=x; this.y=y; this.z=z; token=new CommonToken(ttype,\"\"); }\n" +
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(int ttype, Token t, int x) { token=t; this.x=x;}\n" +
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return (token!=null?token.getText():\"\")+\"<V>;\"+x+y+z;}\n" +
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID -> ID<V>[42,19,30] ID<V>[$ID,99] ;\n"+
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "a", debug);
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("<V>;421930 a<V>;9900\n", found);
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRewriteTokenRoot() throws Exception {
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {static class V extends CommonTree {\n" +
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Token t) { token=t;}\n" +
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT -> ^(ID<V> INT) ;\n"+
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+ ;\n" +
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "a 2", debug);
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(a<V> 2)\n", found);
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRewriteString() throws Exception {
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {static class V extends CommonTree {\n" +
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Token t) { token=t;}\n" +
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : 'begin' -> 'begin'<V> ;\n"+
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "begin", debug);
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("begin<V>\n", found);
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testRewriteStringRoot() throws Exception {
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {static class V extends CommonTree {\n" +
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Token t) { token=t;}\n" +
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : 'begin' INT -> ^('begin'<V> INT) ;\n"+
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+ ;\n" +
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execParser("T.g", grammar, "TParser", "TLexer",
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    "a", "begin 2", debug);
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(begin<V> 2)\n", found);
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testRewriteRuleResults() throws Exception {
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String grammar =
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "grammar T;\n" +
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "options {output=AST;}\n" +
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "tokens {LIST;}\n" +
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "@members {\n" +
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "static class V extends CommonTree {\n" +
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public V(Token t) { token=t;}\n" +
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public String toString() { return token.getText()+\"<V>\";}\n" +
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "}\n" +
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "static class W extends CommonTree {\n" +
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public W(int tokenType, String txt) { super(new CommonToken(tokenType,txt)); }\n" +
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public W(Token t) { token=t;}\n" +
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public String toString() { return token.getText()+\"<W>\";}\n" +
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "}\n" +
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "}\n"+
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : id (',' id)* -> ^(LIST<W>[\"LIST\"] id+);\n" +
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "id : ID -> ID<V>;\n"+
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+ ;\n" +
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String found = execParser("T.g", grammar, "TParser", "TLexer",
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    "a", "a,b,c", debug);
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals("(LIST<W> a<V> b<V> c<V>)\n", found);
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testCopySemanticsWithHetero() throws Exception {
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String grammar =
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "grammar T;\n" +
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "options {output=AST;}\n" +
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "@members {\n" +
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "static class V extends CommonTree {\n" +
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public V(Token t) { token=t;}\n" +  // for 'int'<V>
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public V(V node) { super(node); }\n\n" + // for dupNode
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public Tree dupNode() { return new V(this); }\n" + // for dup'ing type
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "  public String toString() { return token.getText()+\"<V>\";}\n" +
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "}\n" +
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "}\n" +
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "a : type ID (',' ID)* ';' -> ^(type ID)+;\n" +
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "type : 'int'<V> ;\n" +
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+ ;\n" +
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "INT : '0'..'9'+;\n" +
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String found = execParser("T.g", grammar, "TParser", "TLexer",
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    "a", "int a, b, c;", debug);
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals("(int<V> a) (int<V> b) (int<V> c)\n", found);
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // TREE PARSERS -- REWRITE AST
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTreeParserRewriteFlatList() throws Exception {
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT;\n" +
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP;\n"+
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {\n" +
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"static class V extends CommonTree {\n" +
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Object t) { super((CommonTree)t); }\n" +
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"static class W extends CommonTree {\n" +
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public W(Object t) { super((CommonTree)t); }\n" +
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<W>\";}\n" +
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT -> INT<V> ID<W>\n" +
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("34<V> abc<W>\n", found);
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTreeParserRewriteTree() throws Exception {
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT;\n" +
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP;\n"+
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {\n" +
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"static class V extends CommonTree {\n" +
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(Object t) { super((CommonTree)t); }\n" +
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<V>\";}\n" +
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"static class W extends CommonTree {\n" +
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public W(Object t) { super((CommonTree)t); }\n" +
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return token.getText()+\"<W>\";}\n" +
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID INT -> ^(INT<V> ID<W>)\n" +
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(34<V> abc<W>)\n", found);
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTreeParserRewriteImaginary() throws Exception {
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID ;\n" +
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP;\n"+
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tokens { ROOT; }\n" +
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {\n" +
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"class V extends CommonTree {\n" +
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(int tokenType) { super(new CommonToken(tokenType)); }\n" +
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return tokenNames[token.getType()]+\"<V>\";}\n" +
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID -> ROOT<V> ID\n" +
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc");
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("ROOT<V> abc\n", found);
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTreeParserRewriteImaginaryWithArgs() throws Exception {
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID ;\n" +
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP;\n"+
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tokens { ROOT; }\n" +
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {\n" +
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"class V extends CommonTree {\n" +
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public int x;\n" +
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(int tokenType, int x) { super(new CommonToken(tokenType)); this.x=x;}\n" +
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return tokenNames[token.getType()]+\"<V>;\"+x;}\n" +
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID -> ROOT<V>[42] ID\n" +
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc");
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("ROOT<V>;42 abc\n", found);
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTreeParserRewriteImaginaryRoot() throws Exception {
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID ;\n" +
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP;\n"+
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tokens { ROOT; }\n" +
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {\n" +
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"class V extends CommonTree {\n" +
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(int tokenType) { super(new CommonToken(tokenType)); }\n" +
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return tokenNames[token.getType()]+\"<V>\";}\n" +
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID -> ^(ROOT<V> ID)\n" +
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc");
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("(ROOT<V> abc)\n", found);
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTreeParserRewriteImaginaryFromReal() throws Exception {
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID ;\n" +
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP;\n"+
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tokens { ROOT; }\n" +
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {\n" +
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"class V extends CommonTree {\n" +
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(int tokenType) { super(new CommonToken(tokenType)); }\n" +
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(int tokenType, Object tree) { super((CommonTree)tree); token.setType(tokenType); }\n" +
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return tokenNames[token.getType()]+\"<V>@\"+token.getLine();}\n" +
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID -> ROOT<V>[$ID]\n" +
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc");
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("ROOT<V>@1\n", found); // at line 1; shows copy of ID's stuff
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTreeParserAutoHeteroAST() throws Exception {
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammar =
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar T;\n" +
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST;}\n" +
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID ';' ;\n" +
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"ID : 'a'..'z'+ ;\n" +
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"INT : '0'..'9'+;\n" +
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String treeGrammar =
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tree grammar TP;\n"+
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"tokens { ROOT; }\n" +
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"@members {\n" +
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"class V extends CommonTree {\n" +
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public V(CommonTree t) { super(t); }\n" + // NEEDS SPECIAL CTOR
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  public String toString() { return super.toString()+\"<V>\";}\n" +
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n"+
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID<V> ';'<V>\n" +
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n";
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    treeGrammar, "TP", "TLexer", "a", "a", "abc;");
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("abc<V> ;<V>\n", found);
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
545