TestTreeWizard.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.antlr.runtime.tree.CommonTree;
31import org.antlr.runtime.tree.CommonTreeAdaptor;
32import org.antlr.runtime.tree.TreeAdaptor;
33import org.antlr.runtime.tree.TreeWizard;
34import org.junit.Test;
35
36import java.util.ArrayList;
37import java.util.HashMap;
38import java.util.List;
39import java.util.Map;
40
41
42public class TestTreeWizard extends BaseTest {
43	protected static final String[] tokens =
44		new String[] {"", "", "", "", "", "A", "B", "C", "D", "E", "ID", "VAR"};
45	protected static final TreeAdaptor adaptor = new CommonTreeAdaptor();
46
47	@Test public void testSingleNode() throws Exception {
48		TreeWizard wiz = new TreeWizard(adaptor, tokens);
49		CommonTree t = (CommonTree)wiz.create("ID");
50		String found = t.toStringTree();
51		String expecting = "ID";
52		assertEquals(expecting, found);
53	}
54
55	@Test public void testSingleNodeWithArg() throws Exception {
56		TreeWizard wiz = new TreeWizard(adaptor, tokens);
57		CommonTree t = (CommonTree)wiz.create("ID[foo]");
58		String found = t.toStringTree();
59		String expecting = "foo";
60		assertEquals(expecting, found);
61	}
62
63	@Test public void testSingleNodeTree() throws Exception {
64		TreeWizard wiz = new TreeWizard(adaptor, tokens);
65		CommonTree t = (CommonTree)wiz.create("(A)");
66		String found = t.toStringTree();
67		String expecting = "A";
68		assertEquals(expecting, found);
69	}
70
71	@Test public void testSingleLevelTree() throws Exception {
72		TreeWizard wiz = new TreeWizard(adaptor, tokens);
73		CommonTree t = (CommonTree)wiz.create("(A B C D)");
74		String found = t.toStringTree();
75		String expecting = "(A B C D)";
76		assertEquals(expecting, found);
77	}
78
79	@Test public void testListTree() throws Exception {
80		TreeWizard wiz = new TreeWizard(adaptor, tokens);
81		CommonTree t = (CommonTree)wiz.create("(nil A B C)");
82		String found = t.toStringTree();
83		String expecting = "A B C";
84		assertEquals(expecting, found);
85	}
86
87	@Test public void testInvalidListTree() throws Exception {
88		TreeWizard wiz = new TreeWizard(adaptor, tokens);
89		CommonTree t = (CommonTree)wiz.create("A B C");
90		assertTrue(t==null);
91	}
92
93	@Test public void testDoubleLevelTree() throws Exception {
94		TreeWizard wiz = new TreeWizard(adaptor, tokens);
95		CommonTree t = (CommonTree)wiz.create("(A (B C) (B D) E)");
96		String found = t.toStringTree();
97		String expecting = "(A (B C) (B D) E)";
98		assertEquals(expecting, found);
99	}
100
101	@Test public void testSingleNodeIndex() throws Exception {
102		TreeWizard wiz = new TreeWizard(adaptor, tokens);
103		CommonTree t = (CommonTree)wiz.create("ID");
104		Map m = wiz.index(t);
105		String found = m.toString();
106		String expecting = "{10=[ID]}";
107		assertEquals(expecting, found);
108	}
109
110	@Test public void testNoRepeatsIndex() throws Exception {
111		TreeWizard wiz = new TreeWizard(adaptor, tokens);
112		CommonTree t = (CommonTree)wiz.create("(A B C D)");
113		Map m = wiz.index(t);
114		String found = sortMapToString(m);
115        String expecting = "{5=[A], 6=[B], 7=[C], 8=[D]}";
116		assertEquals(expecting, found);
117	}
118
119	@Test public void testRepeatsIndex() throws Exception {
120		TreeWizard wiz = new TreeWizard(adaptor, tokens);
121		CommonTree t = (CommonTree)wiz.create("(A B (A C B) B D D)");
122		Map m = wiz.index(t);
123		String found =  sortMapToString(m);
124        String expecting = "{5=[A, A], 6=[B, B, B], 7=[C], 8=[D, D]}";
125		assertEquals(expecting, found);
126	}
127
128	@Test public void testNoRepeatsVisit() throws Exception {
129		TreeWizard wiz = new TreeWizard(adaptor, tokens);
130		CommonTree t = (CommonTree)wiz.create("(A B C D)");
131		final List elements = new ArrayList();
132		wiz.visit(t, wiz.getTokenType("B"), new TreeWizard.Visitor() {
133			public void visit(Object t) {
134				elements.add(t);
135			}
136		});
137		String found = elements.toString();
138		String expecting = "[B]";
139		assertEquals(expecting, found);
140	}
141
142	@Test public void testNoRepeatsVisit2() throws Exception {
143		TreeWizard wiz = new TreeWizard(adaptor, tokens);
144		CommonTree t = (CommonTree)wiz.create("(A B (A C B) B D D)");
145		final List elements = new ArrayList();
146		wiz.visit(t, wiz.getTokenType("C"),
147					   new TreeWizard.Visitor() {
148							public void visit(Object t) {
149								elements.add(t);
150							}
151					   });
152		String found = elements.toString();
153		String expecting = "[C]";
154		assertEquals(expecting, found);
155	}
156
157	@Test public void testRepeatsVisit() throws Exception {
158		TreeWizard wiz = new TreeWizard(adaptor, tokens);
159		CommonTree t = (CommonTree)wiz.create("(A B (A C B) B D D)");
160		final List elements = new ArrayList();
161		wiz.visit(t, wiz.getTokenType("B"),
162					   new TreeWizard.Visitor() {
163							public void visit(Object t) {
164								elements.add(t);
165							}
166					   });
167		String found = elements.toString();
168		String expecting = "[B, B, B]";
169		assertEquals(expecting, found);
170	}
171
172	@Test public void testRepeatsVisit2() throws Exception {
173		TreeWizard wiz = new TreeWizard(adaptor, tokens);
174		CommonTree t = (CommonTree)wiz.create("(A B (A C B) B D D)");
175		final List elements = new ArrayList();
176		wiz.visit(t, wiz.getTokenType("A"),
177					   new TreeWizard.Visitor() {
178							public void visit(Object t) {
179								elements.add(t);
180							}
181					   });
182		String found = elements.toString();
183		String expecting = "[A, A]";
184		assertEquals(expecting, found);
185	}
186
187	@Test public void testRepeatsVisitWithContext() throws Exception {
188		TreeWizard wiz = new TreeWizard(adaptor, tokens);
189		CommonTree t = (CommonTree)wiz.create("(A B (A C B) B D D)");
190		final List elements = new ArrayList();
191		wiz.visit(t, wiz.getTokenType("B"),
192		   new TreeWizard.ContextVisitor() {
193			   public void visit(Object t, Object parent, int childIndex, Map labels) {
194				   elements.add(adaptor.getText(t)+"@"+
195								(parent!=null?adaptor.getText(parent):"nil")+
196								"["+childIndex+"]");
197			   }
198		   });
199		String found = elements.toString();
200		String expecting = "[B@A[0], B@A[1], B@A[2]]";
201		assertEquals(expecting, found);
202	}
203
204	@Test public void testRepeatsVisitWithNullParentAndContext() throws Exception {
205		TreeWizard wiz = new TreeWizard(adaptor, tokens);
206		CommonTree t = (CommonTree)wiz.create("(A B (A C B) B D D)");
207		final List elements = new ArrayList();
208		wiz.visit(t, wiz.getTokenType("A"),
209		   new TreeWizard.ContextVisitor() {
210			   public void visit(Object t, Object parent, int childIndex, Map labels) {
211				   elements.add(adaptor.getText(t)+"@"+
212								(parent!=null?adaptor.getText(parent):"nil")+
213								"["+childIndex+"]");
214			   }
215		   });
216		String found = elements.toString();
217		String expecting = "[A@nil[0], A@A[1]]";
218		assertEquals(expecting, found);
219	}
220
221	@Test public void testVisitPattern() throws Exception {
222		TreeWizard wiz = new TreeWizard(adaptor, tokens);
223		CommonTree t = (CommonTree)wiz.create("(A B C (A B) D)");
224		final List elements = new ArrayList();
225		wiz.visit(t, "(A B)",
226					   new TreeWizard.Visitor() {
227							public void visit(Object t) {
228								elements.add(t);
229							}
230					   });
231		String found = elements.toString();
232		String expecting = "[A]"; // shouldn't match overall root, just (A B)
233		assertEquals(expecting, found);
234	}
235
236	@Test public void testVisitPatternMultiple() throws Exception {
237		TreeWizard wiz = new TreeWizard(adaptor, tokens);
238		CommonTree t = (CommonTree)wiz.create("(A B C (A B) (D (A B)))");
239		final List elements = new ArrayList();
240		wiz.visit(t, "(A B)",
241					   new TreeWizard.ContextVisitor() {
242						   public void visit(Object t, Object parent, int childIndex, Map labels) {
243							   elements.add(adaptor.getText(t)+"@"+
244											(parent!=null?adaptor.getText(parent):"nil")+
245											"["+childIndex+"]");
246						   }
247					   });
248		String found = elements.toString();
249		String expecting = "[A@A[2], A@D[0]]"; // shouldn't match overall root, just (A B)
250		assertEquals(expecting, found);
251	}
252
253	@Test public void testVisitPatternMultipleWithLabels() throws Exception {
254		TreeWizard wiz = new TreeWizard(adaptor, tokens);
255		CommonTree t = (CommonTree)wiz.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))");
256		final List elements = new ArrayList();
257		wiz.visit(t, "(%a:A %b:B)",
258					   new TreeWizard.ContextVisitor() {
259						   public void visit(Object t, Object parent, int childIndex, Map labels) {
260							   elements.add(adaptor.getText(t)+"@"+
261											(parent!=null?adaptor.getText(parent):"nil")+
262											"["+childIndex+"]"+labels.get("a")+"&"+labels.get("b"));
263						   }
264					   });
265		String found = elements.toString();
266		String expecting = "[foo@A[2]foo&bar, big@D[0]big&dog]";
267		assertEquals(expecting, found);
268	}
269
270	@Test public void testParse() throws Exception {
271		TreeWizard wiz = new TreeWizard(adaptor, tokens);
272		CommonTree t = (CommonTree)wiz.create("(A B C)");
273		boolean valid = wiz.parse(t, "(A B C)");
274		assertTrue(valid);
275	}
276
277	@Test public void testParseSingleNode() throws Exception {
278		TreeWizard wiz = new TreeWizard(adaptor, tokens);
279		CommonTree t = (CommonTree)wiz.create("A");
280		boolean valid = wiz.parse(t, "A");
281		assertTrue(valid);
282	}
283
284	@Test public void testParseFlatTree() throws Exception {
285		TreeWizard wiz = new TreeWizard(adaptor, tokens);
286		CommonTree t = (CommonTree)wiz.create("(nil A B C)");
287		boolean valid = wiz.parse(t, "(nil A B C)");
288		assertTrue(valid);
289	}
290
291	@Test public void testWildcard() throws Exception {
292		TreeWizard wiz = new TreeWizard(adaptor, tokens);
293		CommonTree t = (CommonTree)wiz.create("(A B C)");
294		boolean valid = wiz.parse(t, "(A . .)");
295		assertTrue(valid);
296	}
297
298	@Test public void testParseWithText() throws Exception {
299		TreeWizard wiz = new TreeWizard(adaptor, tokens);
300		CommonTree t = (CommonTree)wiz.create("(A B[foo] C[bar])");
301		// C pattern has no text arg so despite [bar] in t, no need
302		// to match text--check structure only.
303		boolean valid = wiz.parse(t, "(A B[foo] C)");
304		assertTrue(valid);
305	}
306
307	@Test public void testParseWithText2() throws Exception {
308		TreeWizard wiz = new TreeWizard(adaptor, tokens);
309		CommonTree t = (CommonTree)wiz.create("(A B[T__32] (C (D E[a])))");
310		// C pattern has no text arg so despite [bar] in t, no need
311		// to match text--check structure only.
312		boolean valid = wiz.parse(t, "(A B[foo] C)");
313		assertEquals("(A T__32 (C (D a)))", t.toStringTree());
314	}
315
316	@Test public void testParseWithTextFails() throws Exception {
317		TreeWizard wiz = new TreeWizard(adaptor, tokens);
318		CommonTree t = (CommonTree)wiz.create("(A B C)");
319		boolean valid = wiz.parse(t, "(A[foo] B C)");
320		assertTrue(!valid); // fails
321	}
322
323	@Test public void testParseLabels() throws Exception {
324		TreeWizard wiz = new TreeWizard(adaptor, tokens);
325		CommonTree t = (CommonTree)wiz.create("(A B C)");
326		Map labels = new HashMap();
327		boolean valid = wiz.parse(t, "(%a:A %b:B %c:C)", labels);
328		assertTrue(valid);
329		assertEquals("A", labels.get("a").toString());
330		assertEquals("B", labels.get("b").toString());
331		assertEquals("C", labels.get("c").toString());
332	}
333
334	@Test public void testParseWithWildcardLabels() throws Exception {
335		TreeWizard wiz = new TreeWizard(adaptor, tokens);
336		CommonTree t = (CommonTree)wiz.create("(A B C)");
337		Map labels = new HashMap();
338		boolean valid = wiz.parse(t, "(A %b:. %c:.)", labels);
339		assertTrue(valid);
340		assertEquals("B", labels.get("b").toString());
341		assertEquals("C", labels.get("c").toString());
342	}
343
344	@Test public void testParseLabelsAndTestText() throws Exception {
345		TreeWizard wiz = new TreeWizard(adaptor, tokens);
346		CommonTree t = (CommonTree)wiz.create("(A B[foo] C)");
347		Map labels = new HashMap();
348		boolean valid = wiz.parse(t, "(%a:A %b:B[foo] %c:C)", labels);
349		assertTrue(valid);
350		assertEquals("A", labels.get("a").toString());
351		assertEquals("foo", labels.get("b").toString());
352		assertEquals("C", labels.get("c").toString());
353	}
354
355	@Test public void testParseLabelsInNestedTree() throws Exception {
356		TreeWizard wiz = new TreeWizard(adaptor, tokens);
357		CommonTree t = (CommonTree)wiz.create("(A (B C) (D E))");
358		Map labels = new HashMap();
359		boolean valid = wiz.parse(t, "(%a:A (%b:B %c:C) (%d:D %e:E) )", labels);
360		assertTrue(valid);
361		assertEquals("A", labels.get("a").toString());
362		assertEquals("B", labels.get("b").toString());
363		assertEquals("C", labels.get("c").toString());
364		assertEquals("D", labels.get("d").toString());
365		assertEquals("E", labels.get("e").toString());
366	}
367
368	@Test public void testEquals() throws Exception {
369		TreeWizard wiz = new TreeWizard(adaptor, tokens);
370		CommonTree t1 = (CommonTree)wiz.create("(A B C)");
371		CommonTree t2 = (CommonTree)wiz.create("(A B C)");
372		boolean same = TreeWizard.equals(t1, t2, adaptor);
373		assertTrue(same);
374	}
375
376	@Test public void testEqualsWithText() throws Exception {
377		TreeWizard wiz = new TreeWizard(adaptor, tokens);
378		CommonTree t1 = (CommonTree)wiz.create("(A B[foo] C)");
379		CommonTree t2 = (CommonTree)wiz.create("(A B[foo] C)");
380		boolean same = TreeWizard.equals(t1, t2, adaptor);
381		assertTrue(same);
382	}
383
384	@Test public void testEqualsWithMismatchedText() throws Exception {
385		TreeWizard wiz = new TreeWizard(adaptor, tokens);
386		CommonTree t1 = (CommonTree)wiz.create("(A B[foo] C)");
387		CommonTree t2 = (CommonTree)wiz.create("(A B C)");
388		boolean same = TreeWizard.equals(t1, t2, adaptor);
389		assertTrue(!same);
390	}
391
392	@Test public void testFindPattern() throws Exception {
393		TreeWizard wiz = new TreeWizard(adaptor, tokens);
394		CommonTree t = (CommonTree)wiz.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))");
395		final List subtrees = wiz.find(t, "(A B)");
396		List elements = subtrees;
397		String found = elements.toString();
398		String expecting = "[foo, big]";
399		assertEquals(expecting, found);
400	}
401
402}