1/*
2 * [The "BSD license"]
3 *  Copyright (c) 2010 Terence Parr
4 *  All rights reserved.
5 *
6 *  Redistribution and use in source and binary forms, with or without
7 *  modification, are permitted provided that the following conditions
8 *  are met:
9 *  1. Redistributions of source code must retain the above copyright
10 *      notice, this list of conditions and the following disclaimer.
11 *  2. Redistributions in binary form must reproduce the above copyright
12 *      notice, this list of conditions and the following disclaimer in the
13 *      documentation and/or other materials provided with the distribution.
14 *  3. The name of the author may not be used to endorse or promote products
15 *      derived from this software without specific prior written permission.
16 *
17 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28package org.antlr.test;
29
30import org.antlr.Tool;
31import org.antlr.codegen.CodeGenerator;
32import org.antlr.runtime.RecognitionException;
33import org.antlr.tool.ErrorManager;
34import org.antlr.tool.Grammar;
35import org.antlr.tool.GrammarSyntaxMessage;
36import org.junit.Ignore;
37import org.junit.Test;
38
39/** Tree rewrites in tree parsers are basically identical to rewrites
40 *  in a normal grammar except that the atomic element is a node not
41 *  a Token.  Tests here ensure duplication of nodes occurs properly
42 *  and basic functionality.
43 */
44public class TestTreeGrammarRewriteAST extends BaseTest {
45	protected boolean debug = false;
46
47	@Test public void testFlatList() throws Exception {
48		String grammar =
49			"grammar T;\n" +
50			"options {output=AST;}\n" +
51			"a : ID INT;\n" +
52			"ID : 'a'..'z'+ ;\n" +
53			"INT : '0'..'9'+;\n" +
54			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
55
56		String treeGrammar =
57			"tree grammar TP;\n"+
58			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
59			"a : ID INT -> INT ID\n" +
60			"  ;\n";
61
62		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
63									  treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
64		assertEquals("34 abc\n", found);
65	}
66
67	@Test public void testSimpleTree() throws Exception {
68		String grammar =
69			"grammar T;\n" +
70			"options {output=AST;}\n" +
71			"a : ID INT -> ^(ID INT);\n" +
72			"ID : 'a'..'z'+ ;\n" +
73			"INT : '0'..'9'+;\n" +
74			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
75
76		String treeGrammar =
77			"tree grammar TP;\n"+
78			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
79			"a : ^(ID INT) -> ^(INT ID)\n" +
80			"  ;\n";
81
82		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
83									  treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
84		assertEquals("(34 abc)\n", found);
85	}
86
87	@Test public void testNonImaginaryWithCtor() throws Exception {
88		String grammar =
89			"grammar T;\n" +
90			"options {output=AST;}\n" +
91			"a : INT ;\n" +
92			"INT : '0'..'9'+;\n" +
93			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
94
95		String treeGrammar =
96			"tree grammar TP;\n"+
97			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
98			"a : INT -> INT[\"99\"]\n" + // make new INT node
99			"  ;\n";
100
101		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
102				    treeGrammar, "TP", "TLexer", "a", "a", "34");
103		assertEquals("99\n", found);
104	}
105
106	@Test public void testCombinedRewriteAndAuto() throws Exception {
107		String grammar =
108			"grammar T;\n" +
109			"options {output=AST;}\n" +
110			"a : ID INT -> ^(ID INT) | INT ;\n" +
111			"ID : 'a'..'z'+ ;\n" +
112			"INT : '0'..'9'+;\n" +
113			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
114
115		String treeGrammar =
116			"tree grammar TP;\n"+
117			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
118			"a : ^(ID INT) -> ^(INT ID) | INT\n" +
119			"  ;\n";
120
121		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
122									  treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
123		assertEquals("(34 abc)\n", found);
124
125		found = execTreeParser("T.g", grammar, "TParser", "TP.g",
126							   treeGrammar, "TP", "TLexer", "a", "a", "34");
127		assertEquals("34\n", found);
128	}
129
130	@Test public void testAvoidDup() throws Exception {
131		String grammar =
132			"grammar T;\n" +
133			"options {output=AST;}\n" +
134			"a : ID ;\n" +
135			"ID : 'a'..'z'+ ;\n" +
136			"INT : '0'..'9'+;\n" +
137			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
138
139		String treeGrammar =
140			"tree grammar TP;\n"+
141			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
142			"a : ID -> ^(ID ID)\n" +
143			"  ;\n";
144
145		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
146									  treeGrammar, "TP", "TLexer", "a", "a", "abc");
147		assertEquals("(abc abc)\n", found);
148	}
149
150	@Test public void testLoop() throws Exception {
151		String grammar =
152			"grammar T;\n" +
153			"options {output=AST;}\n" +
154			"a : ID+ INT+ -> (^(ID INT))+ ;\n" +
155			"ID : 'a'..'z'+ ;\n" +
156			"INT : '0'..'9'+;\n" +
157			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
158
159		String treeGrammar =
160			"tree grammar TP;\n"+
161			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
162			"a : (^(ID INT))+ -> INT+ ID+\n" +
163			"  ;\n";
164
165		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
166									  treeGrammar, "TP", "TLexer", "a", "a", "a b c 3 4 5");
167		assertEquals("3 4 5 a b c\n", found);
168	}
169
170	@Test public void testAutoDup() throws Exception {
171		String grammar =
172			"grammar T;\n" +
173			"options {output=AST;}\n" +
174			"a : ID ;\n" +
175			"ID : 'a'..'z'+ ;\n" +
176			"INT : '0'..'9'+;\n" +
177			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
178
179		String treeGrammar =
180			"tree grammar TP;\n"+
181			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
182			"a : ID \n" +
183			"  ;\n";
184
185		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
186									  treeGrammar, "TP", "TLexer", "a", "a", "abc");
187		assertEquals("abc\n", found);
188	}
189
190	@Test public void testAutoDupRule() throws Exception {
191		String grammar =
192			"grammar T;\n" +
193			"options {output=AST;}\n" +
194			"a : ID INT ;\n" +
195			"ID : 'a'..'z'+ ;\n" +
196			"INT : '0'..'9'+;\n" +
197			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
198
199		String treeGrammar =
200			"tree grammar TP;\n"+
201			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
202			"a : b c ;\n" +
203			"b : ID ;\n" +
204			"c : INT ;\n";
205
206		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
207									  treeGrammar, "TP", "TLexer", "a", "a", "a 1");
208		assertEquals("a 1\n", found);
209	}
210
211    @Test public void testAutoWildcard() throws Exception {
212        String grammar =
213            "grammar T;\n" +
214            "options {output=AST;}\n" +
215            "a : ID INT ;\n" +
216            "ID : 'a'..'z'+ ;\n" +
217            "INT : '0'..'9'+;\n" +
218            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
219
220        String treeGrammar =
221            "tree grammar TP;\n"+
222            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
223            "a : ID . \n" +
224            "  ;\n";
225
226        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
227                                      treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
228        assertEquals("abc 34\n", found);
229    }
230
231    @Test public void testNoWildcardAsRootError() throws Exception {
232        ErrorQueue equeue = new ErrorQueue();
233        ErrorManager.setErrorListener(equeue);
234
235        String treeGrammar =
236            "tree grammar TP;\n"+
237            "options {output=AST;}\n" +
238            "a : ^(. INT) \n" +
239            "  ;\n";
240
241        Grammar g = new Grammar(treeGrammar);
242        Tool antlr = newTool();
243        antlr.setOutputDirectory(null); // write to /dev/null
244        CodeGenerator generator = new CodeGenerator(antlr, g, "Java");
245        g.setCodeGenerator(generator);
246        generator.genRecognizer();
247
248        assertEquals("unexpected errors: "+equeue, 1, equeue.errors.size());
249
250        int expectedMsgID = ErrorManager.MSG_WILDCARD_AS_ROOT;
251        Object expectedArg = null;
252        RecognitionException expectedExc = null;
253        GrammarSyntaxMessage expectedMessage =
254            new GrammarSyntaxMessage(expectedMsgID, g, null, expectedArg, expectedExc);
255
256        checkError(equeue, expectedMessage);
257    }
258
259    @Test public void testAutoWildcard2() throws Exception {
260        String grammar =
261            "grammar T;\n" +
262            "options {output=AST;}\n" +
263            "a : ID INT -> ^(ID INT);\n" +
264            "ID : 'a'..'z'+ ;\n" +
265            "INT : '0'..'9'+;\n" +
266            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
267
268        String treeGrammar =
269            "tree grammar TP;\n"+
270            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
271            "a : ^(ID .) \n" +
272            "  ;\n";
273
274        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
275                                      treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
276        assertEquals("(abc 34)\n", found);
277    }
278
279    @Test public void testAutoWildcardWithLabel() throws Exception {
280        String grammar =
281            "grammar T;\n" +
282            "options {output=AST;}\n" +
283            "a : ID INT ;\n" +
284            "ID : 'a'..'z'+ ;\n" +
285            "INT : '0'..'9'+;\n" +
286            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
287
288        String treeGrammar =
289            "tree grammar TP;\n"+
290            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
291            "a : ID c=. \n" +
292            "  ;\n";
293
294        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
295                                      treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
296        assertEquals("abc 34\n", found);
297    }
298
299    @Test public void testAutoWildcardWithListLabel() throws Exception {
300        String grammar =
301            "grammar T;\n" +
302            "options {output=AST;}\n" +
303            "a : ID INT ;\n" +
304            "ID : 'a'..'z'+ ;\n" +
305            "INT : '0'..'9'+;\n" +
306            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
307
308        String treeGrammar =
309            "tree grammar TP;\n"+
310            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
311            "a : ID c+=. \n" +
312            "  ;\n";
313
314        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
315                                      treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
316        assertEquals("abc 34\n", found);
317    }
318
319    @Test public void testAutoDupMultiple() throws Exception {
320		String grammar =
321			"grammar T;\n" +
322			"options {output=AST;}\n" +
323			"a : ID ID INT;\n" +
324			"ID : 'a'..'z'+ ;\n" +
325			"INT : '0'..'9'+;\n" +
326			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
327
328		String treeGrammar =
329			"tree grammar TP;\n"+
330			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
331			"a : ID ID INT\n" +
332			"  ;\n";
333
334		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
335									  treeGrammar, "TP", "TLexer", "a", "a", "a b 3");
336		assertEquals("a b 3\n", found);
337	}
338
339	@Test public void testAutoDupTree() throws Exception {
340		String grammar =
341			"grammar T;\n" +
342			"options {output=AST;}\n" +
343			"a : ID INT -> ^(ID INT);\n" +
344			"ID : 'a'..'z'+ ;\n" +
345			"INT : '0'..'9'+;\n" +
346			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
347
348		String treeGrammar =
349			"tree grammar TP;\n"+
350			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
351			"a : ^(ID INT)\n" +
352			"  ;\n";
353
354		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
355									  treeGrammar, "TP", "TLexer", "a", "a", "a 3");
356		assertEquals("(a 3)\n", found);
357	}
358
359	@Test public void testAutoDupTree2() throws Exception {
360		String grammar =
361			"grammar T;\n" +
362			"options {output=AST;}\n" +
363			"a : ID INT INT -> ^(ID INT INT);\n" +
364			"ID : 'a'..'z'+ ;\n" +
365			"INT : '0'..'9'+;\n" +
366			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
367
368		String treeGrammar =
369			"tree grammar TP;\n"+
370			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
371			"a : ^(ID b b)\n" +
372			"  ;\n" +
373			"b : INT ;";
374
375		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
376									  treeGrammar, "TP", "TLexer", "a", "a", "a 3 4");
377		assertEquals("(a 3 4)\n", found);
378	}
379
380	@Test public void testAutoDupTreeWithLabels() throws Exception {
381		String grammar =
382			"grammar T;\n" +
383			"options {output=AST;}\n" +
384			"a : ID INT -> ^(ID INT);\n" +
385			"ID : 'a'..'z'+ ;\n" +
386			"INT : '0'..'9'+;\n" +
387			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
388
389		String treeGrammar =
390			"tree grammar TP;\n"+
391			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
392			"a : ^(x=ID y=INT)\n" +
393			"  ;\n";
394
395		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
396									  treeGrammar, "TP", "TLexer", "a", "a", "a 3");
397		assertEquals("(a 3)\n", found);
398	}
399
400	@Test public void testAutoDupTreeWithListLabels() throws Exception {
401		String grammar =
402			"grammar T;\n" +
403			"options {output=AST;}\n" +
404			"a : ID INT -> ^(ID INT);\n" +
405			"ID : 'a'..'z'+ ;\n" +
406			"INT : '0'..'9'+;\n" +
407			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
408
409		String treeGrammar =
410			"tree grammar TP;\n"+
411			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
412			"a : ^(x+=ID y+=INT)\n" +
413			"  ;\n";
414
415		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
416									  treeGrammar, "TP", "TLexer", "a", "a", "a 3");
417		assertEquals("(a 3)\n", found);
418	}
419
420	@Test public void testAutoDupTreeWithRuleRoot() throws Exception {
421		String grammar =
422			"grammar T;\n" +
423			"options {output=AST;}\n" +
424			"a : ID INT -> ^(ID INT);\n" +
425			"ID : 'a'..'z'+ ;\n" +
426			"INT : '0'..'9'+;\n" +
427			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
428
429		String treeGrammar =
430			"tree grammar TP;\n"+
431			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
432			"a : ^(b INT) ;\n" +
433			"b : ID ;\n";
434
435		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
436									  treeGrammar, "TP", "TLexer", "a", "a", "a 3");
437		assertEquals("(a 3)\n", found);
438	}
439
440	@Test public void testAutoDupTreeWithRuleRootAndLabels() throws Exception {
441		String grammar =
442			"grammar T;\n" +
443			"options {output=AST;}\n" +
444			"a : ID INT -> ^(ID INT);\n" +
445			"ID : 'a'..'z'+ ;\n" +
446			"INT : '0'..'9'+;\n" +
447			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
448
449		String treeGrammar =
450			"tree grammar TP;\n"+
451			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
452			"a : ^(x=b INT) ;\n" +
453			"b : ID ;\n";
454
455		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
456									  treeGrammar, "TP", "TLexer", "a", "a", "a 3");
457		assertEquals("(a 3)\n", found);
458	}
459
460	@Test public void testAutoDupTreeWithRuleRootAndListLabels() throws Exception {
461		String grammar =
462			"grammar T;\n" +
463			"options {output=AST;}\n" +
464			"a : ID INT -> ^(ID INT);\n" +
465			"ID : 'a'..'z'+ ;\n" +
466			"INT : '0'..'9'+;\n" +
467			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
468
469		String treeGrammar =
470			"tree grammar TP;\n"+
471			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
472			"a : ^(x+=b y+=c) ;\n" +
473			"b : ID ;\n" +
474			"c : INT ;\n";
475
476		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
477									  treeGrammar, "TP", "TLexer", "a", "a", "a 3");
478		assertEquals("(a 3)\n", found);
479	}
480
481	@Test public void testAutoDupNestedTree() throws Exception {
482		String grammar =
483			"grammar T;\n" +
484			"options {output=AST;}\n" +
485			"a : x=ID y=ID INT -> ^($x ^($y INT));\n" +
486			"ID : 'a'..'z'+ ;\n" +
487			"INT : '0'..'9'+;\n" +
488			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
489
490		String treeGrammar =
491			"tree grammar TP;\n"+
492			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
493			"a : ^(ID ^(ID INT))\n" +
494			"  ;\n";
495
496		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
497									  treeGrammar, "TP", "TLexer", "a", "a", "a b 3");
498		assertEquals("(a (b 3))\n", found);
499	}
500
501	@Test public void testAutoDupTreeWithSubruleInside() throws Exception {
502		String grammar =
503			"grammar T;\n" +
504			"options {output=AST;}\n" +
505			"tokens {OP;}\n" +
506			"a : (x=ID|x=INT) -> ^(OP $x) ;\n" +
507			"ID : 'a'..'z'+ ;\n" +
508			"INT : '0'..'9'+;\n" +
509			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
510
511		String treeGrammar =
512			"tree grammar TP;\n"+
513			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
514			"a : ^(OP (b|c)) ;\n" +
515			"b : ID ;\n" +
516			"c : INT ;\n";
517
518		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
519									  treeGrammar, "TP", "TLexer", "a", "a", "a");
520		assertEquals("(OP a)\n", found);
521	}
522
523	@Test public void testDelete() throws Exception {
524		String grammar =
525			"grammar T;\n" +
526			"options {output=AST;}\n" +
527			"a : ID ;\n" +
528			"ID : 'a'..'z'+ ;\n" +
529			"INT : '0'..'9'+;\n" +
530			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
531
532		String treeGrammar =
533			"tree grammar TP;\n"+
534			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
535			"a : ID -> \n" +
536			"  ;\n";
537
538		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
539									  treeGrammar, "TP", "TLexer", "a", "a", "abc");
540		assertEquals("", found);
541	}
542
543	@Test public void testSetMatchNoRewrite() throws Exception {
544		String grammar =
545			"grammar T;\n" +
546			"options {output=AST;}\n" +
547			"a : ID INT ;\n" +
548			"ID : 'a'..'z'+ ;\n" +
549			"INT : '0'..'9'+;\n" +
550			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
551
552		String treeGrammar =
553			"tree grammar TP;\n"+
554			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
555			"a : b INT\n" +
556			"  ;\n" +
557			"b : ID | INT ;\n";
558
559		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
560									  treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
561		assertEquals("abc 34\n", found);
562	}
563
564	@Test public void testSetOptionalMatchNoRewrite() throws Exception {
565		String grammar =
566			"grammar T;\n" +
567			"options {output=AST;}\n" +
568			"a : ID INT ;\n" +
569			"ID : 'a'..'z'+ ;\n" +
570			"INT : '0'..'9'+;\n" +
571			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
572
573		String treeGrammar =
574			"tree grammar TP;\n"+
575			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
576			"a : (ID|INT)? INT ;\n";
577
578		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
579									  treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
580		assertEquals("abc 34\n", found);
581	}
582
583
584	@Test public void testSetMatchNoRewriteLevel2() throws Exception {
585		String grammar =
586			"grammar T;\n" +
587			"options {output=AST;}\n" +
588			"a : x=ID INT -> ^($x INT);\n" +
589			"ID : 'a'..'z'+ ;\n" +
590			"INT : '0'..'9'+;\n" +
591			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
592
593		String treeGrammar =
594			"tree grammar TP;\n"+
595			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
596			"a : ^(ID (ID | INT) ) ;\n";
597
598		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
599									  treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
600		assertEquals("(abc 34)\n", found);
601	}
602
603	@Test public void testSetMatchNoRewriteLevel2Root() throws Exception {
604		String grammar =
605			"grammar T;\n" +
606			"options {output=AST;}\n" +
607			"a : x=ID INT -> ^($x INT);\n" +
608			"ID : 'a'..'z'+ ;\n" +
609			"INT : '0'..'9'+;\n" +
610			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
611
612		String treeGrammar =
613			"tree grammar TP;\n"+
614			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
615			"a : ^((ID | INT) INT) ;\n";
616
617		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
618									  treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
619		assertEquals("(abc 34)\n", found);
620	}
621
622
623	// REWRITE MODE
624
625	@Test public void testRewriteModeCombinedRewriteAndAuto() throws Exception {
626		String grammar =
627			"grammar T;\n" +
628			"options {output=AST;}\n" +
629			"a : ID INT -> ^(ID INT) | INT ;\n" +
630			"ID : 'a'..'z'+ ;\n" +
631			"INT : '0'..'9'+;\n" +
632			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
633
634		String treeGrammar =
635			"tree grammar TP;\n"+
636			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
637			"a : ^(ID INT) -> ^(ID[\"ick\"] INT)\n" +
638			"  | INT\n" + // leaves it alone, returning $a.start
639			"  ;\n";
640
641		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
642									  treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
643		assertEquals("(ick 34)\n", found);
644
645		found = execTreeParser("T.g", grammar, "TParser", "TP.g",
646							   treeGrammar, "TP", "TLexer", "a", "a", "34");
647		assertEquals("34\n", found);
648	}
649
650	@Test public void testRewriteModeFlatTree() throws Exception {
651		String grammar =
652			"grammar T;\n" +
653			"options {output=AST;}\n" +
654			"a : ID INT -> ID INT | INT ;\n" +
655			"ID : 'a'..'z'+ ;\n" +
656			"INT : '0'..'9'+;\n" +
657			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
658
659		String treeGrammar =
660			"tree grammar TP;\n"+
661			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
662			"s : ID a ;\n" +
663			"a : INT -> INT[\"1\"]\n"+
664			"  ;\n";
665
666		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
667									  treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
668		assertEquals("abc 1\n", found);
669	}
670
671	@Test public void testRewriteModeChainRuleFlatTree() throws Exception {
672		String grammar =
673			"grammar T;\n" +
674			"options {output=AST;}\n" +
675			"a : ID INT -> ID INT | INT ;\n" +
676			"ID : 'a'..'z'+ ;\n" +
677			"INT : '0'..'9'+;\n" +
678			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
679
680		String treeGrammar =
681			"tree grammar TP;\n"+
682			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
683			"s : a ;\n" +
684			"a : b ;\n" +
685			"b : ID INT -> INT ID\n"+
686			"  ;\n";
687
688		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
689									  treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
690		assertEquals("34 abc\n", found);
691	}
692
693	@Test public void testRewriteModeChainRuleTree() throws Exception {
694		String grammar =
695			"grammar T;\n" +
696			"options {output=AST;}\n" +
697			"a : ID INT -> ^(ID INT) ;\n" +
698			"ID : 'a'..'z'+ ;\n" +
699			"INT : '0'..'9'+;\n" +
700			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
701
702		String treeGrammar =
703			"tree grammar TP;\n"+
704			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
705			"s : a ;\n" +
706			"a : b ;\n" + // a.tree must become b.tree
707			"b : ^(ID INT) -> INT\n"+
708			"  ;\n";
709
710		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
711									  treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
712		assertEquals("34\n", found);
713	}
714
715	@Test public void testRewriteModeChainRuleTree2() throws Exception {
716		String grammar =
717			"grammar T;\n" +
718			"options {output=AST;}\n" +
719			"a : ID INT -> ^(ID INT) ;\n" +
720			"ID : 'a'..'z'+ ;\n" +
721			"INT : '0'..'9'+;\n" +
722			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
723
724		String treeGrammar =
725			"tree grammar TP;\n"+
726			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
727			"tokens { X; }\n" +
728			"s : a* b ;\n" + // only b contributes to tree, but it's after a*; s.tree = b.tree
729			"a : X ;\n" +
730			"b : ^(ID INT) -> INT\n"+
731			"  ;\n";
732
733		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
734									  treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
735		assertEquals("34\n", found);
736	}
737
738	@Test public void testRewriteModeChainRuleTree3() throws Exception {
739		String grammar =
740			"grammar T;\n" +
741			"options {output=AST;}\n" +
742			"a : 'boo' ID INT -> 'boo' ^(ID INT) ;\n" +
743			"ID : 'a'..'z'+ ;\n" +
744			"INT : '0'..'9'+;\n" +
745			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
746
747		String treeGrammar =
748			"tree grammar TP;\n"+
749			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
750			"tokens { X; }\n" +
751			"s : 'boo' a* b ;\n" + // don't reset s.tree to b.tree due to 'boo'
752			"a : X ;\n" +
753			"b : ^(ID INT) -> INT\n"+
754			"  ;\n";
755
756		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
757									  treeGrammar, "TP", "TLexer", "a", "s", "boo abc 34");
758		assertEquals("boo 34\n", found);
759	}
760
761	@Test public void testRewriteModeChainRuleTree4() throws Exception {
762		String grammar =
763			"grammar T;\n" +
764			"options {output=AST;}\n" +
765			"a : 'boo' ID INT -> ^('boo' ^(ID INT)) ;\n" +
766			"ID : 'a'..'z'+ ;\n" +
767			"INT : '0'..'9'+;\n" +
768			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
769
770		String treeGrammar =
771			"tree grammar TP;\n"+
772			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
773			"tokens { X; }\n" +
774			"s : ^('boo' a* b) ;\n" + // don't reset s.tree to b.tree due to 'boo'
775			"a : X ;\n" +
776			"b : ^(ID INT) -> INT\n"+
777			"  ;\n";
778
779		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
780									  treeGrammar, "TP", "TLexer", "a", "s", "boo abc 34");
781		assertEquals("(boo 34)\n", found);
782	}
783
784	@Test public void testRewriteModeChainRuleTree5() throws Exception {
785		String grammar =
786			"grammar T;\n" +
787			"options {output=AST;}\n" +
788			"a : 'boo' ID INT -> ^('boo' ^(ID INT)) ;\n" +
789			"ID : 'a'..'z'+ ;\n" +
790			"INT : '0'..'9'+;\n" +
791			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
792
793		String treeGrammar =
794			"tree grammar TP;\n"+
795			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
796			"tokens { X; }\n" +
797			"s : ^(a b) ;\n" + // s.tree is a.tree
798			"a : 'boo' ;\n" +
799			"b : ^(ID INT) -> INT\n"+
800			"  ;\n";
801
802		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
803									  treeGrammar, "TP", "TLexer", "a", "s", "boo abc 34");
804		assertEquals("(boo 34)\n", found);
805	}
806
807    @Test public void testRewriteOfRuleRef() throws Exception {
808        String grammar =
809            "grammar T;\n" +
810            "options {output=AST;}\n" +
811            "a : ID INT -> ID INT | INT ;\n" +
812            "ID : 'a'..'z'+ ;\n" +
813            "INT : '0'..'9'+;\n" +
814            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
815
816        String treeGrammar =
817            "tree grammar TP;\n"+
818            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
819            "s : a -> a ;\n" +
820            "a : ID INT -> ID INT ;\n";
821
822        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
823                                      treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
824        assertEquals("abc 34\n", found);
825    }
826
827    @Test public void testRewriteOfRuleRefRoot() throws Exception {
828        String grammar =
829            "grammar T;\n" +
830            "options {output=AST;}\n" +
831            "a : ID INT INT -> ^(INT ^(ID INT));\n" +
832            "ID : 'a'..'z'+ ;\n" +
833            "INT : '0'..'9'+;\n" +
834            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
835
836        String treeGrammar =
837            "tree grammar TP;\n"+
838            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
839            "s : ^(a ^(ID INT)) -> a ;\n" +
840            "a : INT ;\n";
841
842        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
843                                      treeGrammar, "TP", "TLexer", "a", "s", "abc 12 34");
844        // emits whole tree when you ref the root since I can't know whether
845        // you want the children or not.  You might be returning a whole new
846        // tree.  Hmm...still seems weird.  oh well.
847        assertEquals("(12 (abc 34))\n", found);
848    }
849
850    @Test public void testRewriteOfRuleRefRootLabeled() throws Exception {
851        String grammar =
852            "grammar T;\n" +
853            "options {output=AST;}\n" +
854            "a : ID INT INT -> ^(INT ^(ID INT));\n" +
855            "ID : 'a'..'z'+ ;\n" +
856            "INT : '0'..'9'+;\n" +
857            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
858
859        String treeGrammar =
860            "tree grammar TP;\n"+
861            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
862            "s : ^(label=a ^(ID INT)) -> a ;\n" +
863            "a : INT ;\n";
864
865        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
866                                      treeGrammar, "TP", "TLexer", "a", "s", "abc 12 34");
867        // emits whole tree when you ref the root since I can't know whether
868        // you want the children or not.  You might be returning a whole new
869        // tree.  Hmm...still seems weird.  oh well.
870        assertEquals("(12 (abc 34))\n", found);
871    }
872
873    @Ignore
874    @Test public void testRewriteOfRuleRefRootListLabeled() throws Exception {
875        String grammar =
876            "grammar T;\n" +
877            "options {output=AST;}\n" +
878            "a : ID INT INT -> ^(INT ^(ID INT));\n" +
879            "ID : 'a'..'z'+ ;\n" +
880            "INT : '0'..'9'+;\n" +
881            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
882
883        String treeGrammar =
884            "tree grammar TP;\n"+
885            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
886            "s : ^(label+=a ^(ID INT)) -> a ;\n" +
887            "a : INT ;\n";
888
889        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
890                                      treeGrammar, "TP", "TLexer", "a", "s", "abc 12 34");
891        // emits whole tree when you ref the root since I can't know whether
892        // you want the children or not.  You might be returning a whole new
893        // tree.  Hmm...still seems weird.  oh well.
894        assertEquals("(12 (abc 34))\n", found);
895    }
896
897    @Test public void testRewriteOfRuleRefChild() throws Exception {
898        String grammar =
899            "grammar T;\n" +
900            "options {output=AST;}\n" +
901            "a : ID INT -> ^(ID ^(INT INT));\n" +
902            "ID : 'a'..'z'+ ;\n" +
903            "INT : '0'..'9'+;\n" +
904            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
905
906        String treeGrammar =
907            "tree grammar TP;\n"+
908            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
909            "s : ^(ID a) -> a ;\n" +
910            "a : ^(INT INT) ;\n";
911
912        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
913                                      treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
914        assertEquals("(34 34)\n", found);
915    }
916
917    @Test public void testRewriteOfRuleRefLabel() throws Exception {
918        String grammar =
919            "grammar T;\n" +
920            "options {output=AST;}\n" +
921            "a : ID INT -> ^(ID ^(INT INT));\n" +
922            "ID : 'a'..'z'+ ;\n" +
923            "INT : '0'..'9'+;\n" +
924            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
925
926        String treeGrammar =
927            "tree grammar TP;\n"+
928            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
929            "s : ^(ID label=a) -> a ;\n" +
930            "a : ^(INT INT) ;\n";
931
932        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
933                                      treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
934        assertEquals("(34 34)\n", found);
935    }
936
937    @Test public void testRewriteOfRuleRefListLabel() throws Exception {
938        String grammar =
939            "grammar T;\n" +
940            "options {output=AST;}\n" +
941            "a : ID INT -> ^(ID ^(INT INT));\n" +
942            "ID : 'a'..'z'+ ;\n" +
943            "INT : '0'..'9'+;\n" +
944            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
945
946        String treeGrammar =
947            "tree grammar TP;\n"+
948            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
949            "s : ^(ID label+=a) -> a ;\n" +
950            "a : ^(INT INT) ;\n";
951
952        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
953                                      treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
954        assertEquals("(34 34)\n", found);
955    }
956
957    @Test public void testRewriteModeWithPredicatedRewrites() throws Exception {
958		String grammar =
959			"grammar T;\n" +
960			"options {output=AST;}\n" +
961			"a : ID INT -> ^(ID[\"root\"] ^(ID INT)) | INT -> ^(ID[\"root\"] INT) ;\n" +
962			"ID : 'a'..'z'+ ;\n" +
963			"INT : '0'..'9'+;\n" +
964			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
965
966		String treeGrammar =
967			"tree grammar TP;\n"+
968			"options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
969			"s : ^(ID a) {System.out.println(\"altered tree=\"+$s.start.toStringTree());};\n" +
970			"a : ^(ID INT) -> {true}? ^(ID[\"ick\"] INT)\n" +
971			"              -> INT\n" +
972			"  ;\n";
973
974		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
975									  treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
976		assertEquals("altered tree=(root (ick 34))\n" +
977					 "(root (ick 34))\n", found);
978	}
979
980    @Test public void testWildcardSingleNode() throws Exception {
981        String grammar =
982            "grammar T;\n" +
983            "options {output=AST;}\n" +
984            "a : ID INT -> ^(ID[\"root\"] INT);\n"+
985            "ID : 'a'..'z'+ ;\n" +
986            "INT : '0'..'9'+;\n" +
987            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
988
989        String treeGrammar =
990            "tree grammar TP;\n"+
991            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
992            "s : ^(ID c=.) -> $c\n" +
993            "  ;\n";
994
995        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
996                                      treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
997        assertEquals("34\n", found);
998    }
999
1000    @Test public void testWildcardUnlabeledSingleNode() throws Exception {
1001        String grammar =
1002            "grammar T;\n" +
1003            "options {output=AST;}\n" +
1004            "a : ID INT -> ^(ID INT);\n"+
1005            "ID : 'a'..'z'+ ;\n" +
1006            "INT : '0'..'9'+;\n" +
1007            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
1008
1009        String treeGrammar =
1010            "tree grammar TP;\n"+
1011            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
1012            "s : ^(ID .) -> ID\n" +
1013            "  ;\n";
1014
1015        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
1016                                      treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
1017        assertEquals("abc\n", found);
1018    }
1019
1020    @Test public void testWildcardGrabsSubtree() throws Exception {
1021        String grammar =
1022            "grammar T;\n" +
1023            "options {output=AST;}\n" +
1024            "a : ID x=INT y=INT z=INT -> ^(ID[\"root\"] ^($x $y $z));\n"+
1025            "ID : 'a'..'z'+ ;\n" +
1026            "INT : '0'..'9'+;\n" +
1027            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
1028
1029        String treeGrammar =
1030            "tree grammar TP;\n"+
1031            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
1032            "s : ^(ID c=.) -> $c\n" +
1033            "  ;\n";
1034
1035        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
1036                                      treeGrammar, "TP", "TLexer", "a", "s", "abc 1 2 3");
1037        assertEquals("(1 2 3)\n", found);
1038    }
1039
1040    @Test public void testWildcardGrabsSubtree2() throws Exception {
1041        String grammar =
1042            "grammar T;\n" +
1043            "options {output=AST;}\n" +
1044            "a : ID x=INT y=INT z=INT -> ID ^($x $y $z);\n"+
1045            "ID : 'a'..'z'+ ;\n" +
1046            "INT : '0'..'9'+;\n" +
1047            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
1048
1049        String treeGrammar =
1050            "tree grammar TP;\n"+
1051            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
1052            "s : ID c=. -> $c\n" +
1053            "  ;\n";
1054
1055        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
1056                                      treeGrammar, "TP", "TLexer", "a", "s", "abc 1 2 3");
1057        assertEquals("(1 2 3)\n", found);
1058    }
1059
1060    @Test public void testWildcardListLabel() throws Exception {
1061        String grammar =
1062            "grammar T;\n" +
1063            "options {output=AST;}\n" +
1064            "a : INT INT INT ;\n"+
1065            "ID : 'a'..'z'+ ;\n" +
1066            "INT : '0'..'9'+;\n" +
1067            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
1068
1069        String treeGrammar =
1070            "tree grammar TP;\n"+
1071            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
1072            "s : (c+=.)+ -> $c+\n" +
1073            "  ;\n";
1074
1075        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
1076                                      treeGrammar, "TP", "TLexer", "a", "s", "1 2 3");
1077        assertEquals("1 2 3\n", found);
1078    }
1079
1080    @Test public void testWildcardListLabel2() throws Exception {
1081        String grammar =
1082            "grammar T;\n" +
1083            "options {output=AST; ASTLabelType=CommonTree;}\n" +
1084            "a  : x=INT y=INT z=INT -> ^($x ^($y $z) ^($y $z));\n"+
1085            "ID : 'a'..'z'+ ;\n" +
1086            "INT : '0'..'9'+;\n" +
1087            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
1088
1089        String treeGrammar =
1090            "tree grammar TP;\n"+
1091            "options {output=AST; ASTLabelType=CommonTree; tokenVocab=T; rewrite=true;}\n" +
1092            "s : ^(INT (c+=.)+) -> $c+\n" +
1093            "  ;\n";
1094
1095        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
1096                                      treeGrammar, "TP", "TLexer", "a", "s", "1 2 3");
1097        assertEquals("(2 3) (2 3)\n", found);
1098    }
1099
1100	@Test public void testRuleResultAsRoot() throws Exception {
1101		String grammar =
1102			"grammar T;\n" +
1103			"options {output=AST;}\n" +
1104			"a : ID '=' INT -> ^('=' ID INT);\n" +
1105			"ID : 'a'..'z'+ ;\n" +
1106			"INT : '0'..'9'+;\n" +
1107			"COLON : ':' ;\n" +
1108			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
1109
1110		String treeGrammar =
1111			"tree grammar TP;\n"+
1112			"options {output=AST; rewrite=true; ASTLabelType=CommonTree; tokenVocab=T;}\n" +
1113			"a : ^(eq e1=ID e2=.) -> ^(eq $e2 $e1) ;\n" +
1114			"eq : '=' | ':' {;} ;\n";  // bug in set match, doesn't add to tree!! booh. force nonset.
1115
1116		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
1117									  treeGrammar, "TP", "TLexer", "a", "a", "abc = 34");
1118		assertEquals("(= 34 abc)\n", found);
1119	}
1120
1121}
1122