TestTreeParsing.java revision 324c4644fee44b9898524c09511bd33c3f12e2df
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.junit.Test;
31
32public class TestTreeParsing extends BaseTest {
33	@Test public void testFlatList() throws Exception {
34		String grammar =
35			"grammar T;\n" +
36			"options {output=AST;}\n" +
37			"a : ID INT;\n" +
38			"ID : 'a'..'z'+ ;\n" +
39			"INT : '0'..'9'+;\n" +
40			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
41
42		String treeGrammar =
43			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
44			"a : ID INT\n" +
45			"    {System.out.println($ID+\", \"+$INT);}\n" +
46			"  ;\n";
47
48		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
49				    treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
50		assertEquals("abc, 34\n", found);
51	}
52
53	@Test public void testSimpleTree() throws Exception {
54		String grammar =
55			"grammar T;\n" +
56			"options {output=AST;}\n" +
57			"a : ID INT -> ^(ID INT);\n" +
58			"ID : 'a'..'z'+ ;\n" +
59			"INT : '0'..'9'+;\n" +
60			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
61
62		String treeGrammar =
63			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
64			"a : ^(ID INT)\n" +
65			"    {System.out.println($ID+\", \"+$INT);}\n" +
66			"  ;\n";
67
68		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
69				    treeGrammar, "TP", "TLexer", "a", "a", "abc 34");
70		assertEquals("abc, 34\n", found);
71	}
72
73	@Test public void testFlatVsTreeDecision() throws Exception {
74		String grammar =
75			"grammar T;\n" +
76			"options {output=AST;}\n" +
77			"a : b c ;\n" +
78			"b : ID INT -> ^(ID INT);\n" +
79			"c : ID INT;\n" +
80			"ID : 'a'..'z'+ ;\n" +
81			"INT : '0'..'9'+;\n" +
82			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
83
84		String treeGrammar =
85			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
86			"a : b b ;\n" +
87			"b : ID INT    {System.out.print($ID+\" \"+$INT);}\n" +
88			"  | ^(ID INT) {System.out.print(\"^(\"+$ID+\" \"+$INT+')');}\n" +
89			"  ;\n";
90
91		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
92				    treeGrammar, "TP", "TLexer", "a", "a", "a 1 b 2");
93		assertEquals("^(a 1)b 2\n", found);
94	}
95
96	@Test public void testFlatVsTreeDecision2() throws Exception {
97		String grammar =
98			"grammar T;\n" +
99			"options {output=AST;}\n" +
100			"a : b c ;\n" +
101			"b : ID INT+ -> ^(ID INT+);\n" +
102			"c : ID INT+;\n" +
103			"ID : 'a'..'z'+ ;\n" +
104			"INT : '0'..'9'+;\n" +
105			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
106
107		String treeGrammar =
108			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
109			"a : b b ;\n" +
110			"b : ID INT+    {System.out.print($ID+\" \"+$INT);}\n" +
111			"  | ^(x=ID (y=INT)+) {System.out.print(\"^(\"+$x+' '+$y+')');}\n" +
112			"  ;\n";
113
114		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
115				    treeGrammar, "TP", "TLexer", "a", "a",
116				    "a 1 2 3 b 4 5");
117		assertEquals("^(a 3)b 5\n", found);
118	}
119
120	@Test public void testCyclicDFALookahead() throws Exception {
121		String grammar =
122			"grammar T;\n" +
123			"options {output=AST;}\n" +
124			"a : ID INT+ PERIOD;\n" +
125			"ID : 'a'..'z'+ ;\n" +
126			"INT : '0'..'9'+;\n" +
127			"SEMI : ';' ;\n"+
128			"PERIOD : '.' ;\n"+
129			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
130
131		String treeGrammar =
132			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
133			"a : ID INT+ PERIOD {System.out.print(\"alt 1\");}"+
134			"  | ID INT+ SEMI   {System.out.print(\"alt 2\");}\n" +
135			"  ;\n";
136
137		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
138				    treeGrammar, "TP", "TLexer", "a", "a", "a 1 2 3.");
139		assertEquals("alt 1\n", found);
140	}
141
142	@Test public void testTemplateOutput() throws Exception {
143		String grammar =
144			"grammar T;\n" +
145			"options {output=AST;}\n" +
146			"a : ID INT;\n" +
147			"ID : 'a'..'z'+ ;\n" +
148			"INT : '0'..'9'+;\n" +
149			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
150
151		String treeGrammar =
152			"tree grammar TP;\n" +
153			"options {output=template; ASTLabelType=CommonTree;}\n" +
154			"s : a {System.out.println($a.st);};\n" +
155			"a : ID INT -> {new StringTemplate($INT.text)}\n" +
156			"  ;\n";
157
158		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
159				    treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
160		assertEquals("34\n", found);
161	}
162
163	@Test public void testNullableChildList() throws Exception {
164		String grammar =
165			"grammar T;\n" +
166			"options {output=AST;}\n" +
167			"a : ID INT? -> ^(ID INT?);\n" +
168			"ID : 'a'..'z'+ ;\n" +
169			"INT : '0'..'9'+;\n" +
170			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
171
172		String treeGrammar =
173			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
174			"a : ^(ID INT?)\n" +
175			"    {System.out.println($ID);}\n" +
176			"  ;\n";
177
178		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
179				    treeGrammar, "TP", "TLexer", "a", "a", "abc");
180		assertEquals("abc\n", found);
181	}
182
183	@Test public void testNullableChildList2() throws Exception {
184		String grammar =
185			"grammar T;\n" +
186			"options {output=AST;}\n" +
187			"a : ID INT? SEMI -> ^(ID INT?) SEMI ;\n" +
188			"ID : 'a'..'z'+ ;\n" +
189			"INT : '0'..'9'+;\n" +
190			"SEMI : ';' ;\n"+
191			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
192
193		String treeGrammar =
194			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
195			"a : ^(ID INT?) SEMI\n" +
196			"    {System.out.println($ID);}\n" +
197			"  ;\n";
198
199		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
200				    treeGrammar, "TP", "TLexer", "a", "a", "abc;");
201		assertEquals("abc\n", found);
202	}
203
204	@Test public void testNullableChildList3() throws Exception {
205		String grammar =
206			"grammar T;\n" +
207			"options {output=AST;}\n" +
208			"a : x=ID INT? (y=ID)? SEMI -> ^($x INT? $y?) SEMI ;\n" +
209			"ID : 'a'..'z'+ ;\n" +
210			"INT : '0'..'9'+;\n" +
211			"SEMI : ';' ;\n"+
212			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
213
214		String treeGrammar =
215			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
216			"a : ^(ID INT? b) SEMI\n" +
217			"    {System.out.println($ID+\", \"+$b.text);}\n" +
218			"  ;\n"+
219			"b : ID? ;\n";
220
221		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
222				    treeGrammar, "TP", "TLexer", "a", "a", "abc def;");
223		assertEquals("abc, def\n", found);
224	}
225
226	@Test public void testActionsAfterRoot() throws Exception {
227		String grammar =
228			"grammar T;\n" +
229			"options {output=AST;}\n" +
230			"a : x=ID INT? SEMI -> ^($x INT?) ;\n" +
231			"ID : 'a'..'z'+ ;\n" +
232			"INT : '0'..'9'+;\n" +
233			"SEMI : ';' ;\n"+
234			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
235
236		String treeGrammar =
237			"tree grammar TP; options {ASTLabelType=CommonTree;}\n" +
238			"a @init {int x=0;} : ^(ID {x=1;} {x=2;} INT?)\n" +
239			"    {System.out.println($ID+\", \"+x);}\n" +
240			"  ;\n";
241
242		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
243				    treeGrammar, "TP", "TLexer", "a", "a", "abc;");
244		assertEquals("abc, 2\n", found);
245	}
246
247    @Test public void testWildcardLookahead() throws Exception {
248        String grammar =
249            "grammar T;\n" +
250            "options {output=AST;}\n" +
251            "a : ID '+'^ INT;\n" +
252            "ID : 'a'..'z'+ ;\n" +
253            "INT : '0'..'9'+;\n" +
254            "SEMI : ';' ;\n"+
255            "PERIOD : '.' ;\n"+
256            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
257
258        String treeGrammar =
259            "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" +
260            "a : ^('+' . INT) {System.out.print(\"alt 1\");}"+
261            "  ;\n";
262
263        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
264                    treeGrammar, "TP", "TLexer", "a", "a", "a + 2");
265        assertEquals("alt 1\n", found);
266    }
267
268    @Test public void testWildcardLookahead2() throws Exception {
269        String grammar =
270            "grammar T;\n" +
271            "options {output=AST;}\n" +
272            "a : ID '+'^ INT;\n" +
273            "ID : 'a'..'z'+ ;\n" +
274            "INT : '0'..'9'+;\n" +
275            "SEMI : ';' ;\n"+
276            "PERIOD : '.' ;\n"+
277            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
278
279        String treeGrammar =
280            "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" +
281            "a : ^('+' . INT) {System.out.print(\"alt 1\");}"+
282            "  | ^('+' . .)   {System.out.print(\"alt 2\");}\n" +
283            "  ;\n";
284
285        // AMBIG upon '+' DOWN INT UP etc.. but so what.
286
287        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
288                    treeGrammar, "TP", "TLexer", "a", "a", "a + 2");
289        assertEquals("alt 1\n", found);
290    }
291
292    @Test public void testWildcardLookahead3() throws Exception {
293        String grammar =
294            "grammar T;\n" +
295            "options {output=AST;}\n" +
296            "a : ID '+'^ INT;\n" +
297            "ID : 'a'..'z'+ ;\n" +
298            "INT : '0'..'9'+;\n" +
299            "SEMI : ';' ;\n"+
300            "PERIOD : '.' ;\n"+
301            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
302
303        String treeGrammar =
304            "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" +
305            "a : ^('+' ID INT) {System.out.print(\"alt 1\");}"+
306            "  | ^('+' . .)   {System.out.print(\"alt 2\");}\n" +
307            "  ;\n";
308
309        // AMBIG upon '+' DOWN INT UP etc.. but so what.
310
311        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
312                    treeGrammar, "TP", "TLexer", "a", "a", "a + 2");
313        assertEquals("alt 1\n", found);
314    }
315
316    @Test public void testWildcardPlusLookahead() throws Exception {
317        String grammar =
318            "grammar T;\n" +
319            "options {output=AST;}\n" +
320            "a : ID '+'^ INT;\n" +
321            "ID : 'a'..'z'+ ;\n" +
322            "INT : '0'..'9'+;\n" +
323            "SEMI : ';' ;\n"+
324            "PERIOD : '.' ;\n"+
325            "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
326
327        String treeGrammar =
328            "tree grammar TP; options {tokenVocab=T; ASTLabelType=CommonTree;}\n" +
329            "a : ^('+' INT INT ) {System.out.print(\"alt 1\");}"+
330            "  | ^('+' .+)   {System.out.print(\"alt 2\");}\n" +
331            "  ;\n";
332
333        // AMBIG upon '+' DOWN INT UP etc.. but so what.
334
335        String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
336                    treeGrammar, "TP", "TLexer", "a", "a", "a + 2");
337        assertEquals("alt 2\n", found);
338    }
339
340}
341