• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
28 package org.antlr.test;
29 
30 import org.antlr.runtime.CommonToken;
31 import org.antlr.runtime.Token;
32 import org.antlr.runtime.tree.*;
33 import org.junit.Test;
34 
35 /** Test the tree node stream. */
36 public class TestTreeNodeStream extends BaseTest {
37 
38 	/** Build new stream; let's us override to test other streams. */
newStream(Object t)39 	public TreeNodeStream newStream(Object t) {
40 		return new CommonTreeNodeStream(t);
41 	}
42 
toTokenTypeString(TreeNodeStream stream)43     public String toTokenTypeString(TreeNodeStream stream) {
44         return ((CommonTreeNodeStream)stream).toTokenTypeString();
45     }
46 
testSingleNode()47 	@Test public void testSingleNode() throws Exception {
48 		Tree t = new CommonTree(new CommonToken(101));
49 
50 		TreeNodeStream stream = newStream(t);
51 		String expecting = " 101";
52 		String found = toNodesOnlyString(stream);
53 		assertEquals(expecting, found);
54 
55 		expecting = " 101";
56 		found = toTokenTypeString(stream);
57 		assertEquals(expecting, found);
58 	}
59 
test4Nodes()60 	@Test public void test4Nodes() throws Exception {
61 		// ^(101 ^(102 103) 104)
62 		Tree t = new CommonTree(new CommonToken(101));
63 		t.addChild(new CommonTree(new CommonToken(102)));
64 		t.getChild(0).addChild(new CommonTree(new CommonToken(103)));
65 		t.addChild(new CommonTree(new CommonToken(104)));
66 
67 		TreeNodeStream stream = newStream(t);
68 		String expecting = " 101 102 103 104";
69 		String found = toNodesOnlyString(stream);
70 		assertEquals(expecting, found);
71 
72 		expecting = " 101 2 102 2 103 3 104 3";
73 		found = toTokenTypeString(stream);
74 		assertEquals(expecting, found);
75 	}
76 
testList()77 	@Test public void testList() throws Exception {
78 		Tree root = new CommonTree((Token)null);
79 
80 		Tree t = new CommonTree(new CommonToken(101));
81 		t.addChild(new CommonTree(new CommonToken(102)));
82 		t.getChild(0).addChild(new CommonTree(new CommonToken(103)));
83 		t.addChild(new CommonTree(new CommonToken(104)));
84 
85 		Tree u = new CommonTree(new CommonToken(105));
86 
87 		root.addChild(t);
88 		root.addChild(u);
89 
90 		TreeNodeStream stream = newStream(root);
91 		String expecting = " 101 102 103 104 105";
92 		String found = toNodesOnlyString(stream);
93 		assertEquals(expecting, found);
94 
95 		expecting = " 101 2 102 2 103 3 104 3 105";
96 		found = toTokenTypeString(stream);
97 		assertEquals(expecting, found);
98 	}
99 
testFlatList()100 	@Test public void testFlatList() throws Exception {
101 		Tree root = new CommonTree((Token)null);
102 
103 		root.addChild(new CommonTree(new CommonToken(101)));
104 		root.addChild(new CommonTree(new CommonToken(102)));
105 		root.addChild(new CommonTree(new CommonToken(103)));
106 
107 		TreeNodeStream stream = newStream(root);
108 		String expecting = " 101 102 103";
109 		String found = toNodesOnlyString(stream);
110 		assertEquals(expecting, found);
111 
112 		expecting = " 101 102 103";
113 		found = toTokenTypeString(stream);
114 		assertEquals(expecting, found);
115 	}
116 
testListWithOneNode()117 	@Test public void testListWithOneNode() throws Exception {
118 		Tree root = new CommonTree((Token)null);
119 
120 		root.addChild(new CommonTree(new CommonToken(101)));
121 
122 		TreeNodeStream stream = newStream(root);
123 		String expecting = " 101";
124 		String found = toNodesOnlyString(stream);
125 		assertEquals(expecting, found);
126 
127 		expecting = " 101";
128 		found = toTokenTypeString(stream);
129 		assertEquals(expecting, found);
130 	}
131 
testAoverB()132 	@Test public void testAoverB() throws Exception {
133 		Tree t = new CommonTree(new CommonToken(101));
134 		t.addChild(new CommonTree(new CommonToken(102)));
135 
136 		TreeNodeStream stream = newStream(t);
137 		String expecting = " 101 102";
138 		String found = toNodesOnlyString(stream);
139 		assertEquals(expecting, found);
140 
141 		expecting = " 101 2 102 3";
142 		found = toTokenTypeString(stream);
143 		assertEquals(expecting, found);
144 	}
145 
testLT()146 	@Test public void testLT() throws Exception {
147 		// ^(101 ^(102 103) 104)
148 		Tree t = new CommonTree(new CommonToken(101));
149 		t.addChild(new CommonTree(new CommonToken(102)));
150 		t.getChild(0).addChild(new CommonTree(new CommonToken(103)));
151 		t.addChild(new CommonTree(new CommonToken(104)));
152 
153 		TreeNodeStream stream = newStream(t);
154 		assertEquals(101, ((Tree)stream.LT(1)).getType());
155 		assertEquals(Token.DOWN, ((Tree)stream.LT(2)).getType());
156 		assertEquals(102, ((Tree)stream.LT(3)).getType());
157 		assertEquals(Token.DOWN, ((Tree)stream.LT(4)).getType());
158 		assertEquals(103, ((Tree)stream.LT(5)).getType());
159 		assertEquals(Token.UP, ((Tree)stream.LT(6)).getType());
160 		assertEquals(104, ((Tree)stream.LT(7)).getType());
161 		assertEquals(Token.UP, ((Tree)stream.LT(8)).getType());
162 		assertEquals(Token.EOF, ((Tree)stream.LT(9)).getType());
163 		// check way ahead
164 		assertEquals(Token.EOF, ((Tree)stream.LT(100)).getType());
165 	}
166 
testMarkRewindEntire()167 	@Test public void testMarkRewindEntire() throws Exception {
168 		// ^(101 ^(102 103 ^(106 107) ) 104 105)
169 		// stream has 7 real + 6 nav nodes
170 		// Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
171 		Tree r0 = new CommonTree(new CommonToken(101));
172 		Tree r1 = new CommonTree(new CommonToken(102));
173 		r0.addChild(r1);
174 		r1.addChild(new CommonTree(new CommonToken(103)));
175 		Tree r2 = new CommonTree(new CommonToken(106));
176 		r2.addChild(new CommonTree(new CommonToken(107)));
177 		r1.addChild(r2);
178 		r0.addChild(new CommonTree(new CommonToken(104)));
179 		r0.addChild(new CommonTree(new CommonToken(105)));
180 
181 		TreeNodeStream stream = newStream(r0);
182 		int m = stream.mark(); // MARK
183 		for (int k=1; k<=13; k++) { // consume til end
184 			stream.LT(1);
185 			stream.consume();
186 		}
187 		assertEquals(Token.EOF, ((Tree)stream.LT(1)).getType());
188 		stream.rewind(m);      // REWIND
189 
190 		// consume til end again :)
191 		for (int k=1; k<=13; k++) { // consume til end
192 			stream.LT(1);
193 			stream.consume();
194 		}
195 		assertEquals(Token.EOF, ((Tree)stream.LT(1)).getType());
196 	}
197 
testMarkRewindInMiddle()198 	@Test public void testMarkRewindInMiddle() throws Exception {
199 		// ^(101 ^(102 103 ^(106 107) ) 104 105)
200 		// stream has 7 real + 6 nav nodes
201 		// Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
202 		Tree r0 = new CommonTree(new CommonToken(101));
203 		Tree r1 = new CommonTree(new CommonToken(102));
204 		r0.addChild(r1);
205 		r1.addChild(new CommonTree(new CommonToken(103)));
206 		Tree r2 = new CommonTree(new CommonToken(106));
207 		r2.addChild(new CommonTree(new CommonToken(107)));
208 		r1.addChild(r2);
209 		r0.addChild(new CommonTree(new CommonToken(104)));
210 		r0.addChild(new CommonTree(new CommonToken(105)));
211 
212 		TreeNodeStream stream = newStream(r0);
213 		for (int k=1; k<=7; k++) { // consume til middle
214 			//System.out.println(((Tree)stream.LT(1)).getType());
215 			stream.consume();
216 		}
217 		assertEquals(107, ((Tree)stream.LT(1)).getType());
218 		stream.mark(); // MARK
219 		stream.consume(); // consume 107
220 		stream.consume(); // consume UP
221 		stream.consume(); // consume UP
222 		stream.consume(); // consume 104
223 		stream.rewind(); // REWIND
224         stream.mark();   // keep saving nodes though
225 
226 		assertEquals(107, ((Tree)stream.LT(1)).getType());
227 		stream.consume();
228 		assertEquals(Token.UP, ((Tree)stream.LT(1)).getType());
229 		stream.consume();
230 		assertEquals(Token.UP, ((Tree)stream.LT(1)).getType());
231 		stream.consume();
232 		assertEquals(104, ((Tree)stream.LT(1)).getType());
233 		stream.consume();
234 		// now we're past rewind position
235 		assertEquals(105, ((Tree)stream.LT(1)).getType());
236 		stream.consume();
237 		assertEquals(Token.UP, ((Tree)stream.LT(1)).getType());
238 		stream.consume();
239 		assertEquals(Token.EOF, ((Tree)stream.LT(1)).getType());
240 		assertEquals(Token.UP, ((Tree)stream.LT(-1)).getType());
241 	}
242 
testMarkRewindNested()243 	@Test public void testMarkRewindNested() throws Exception {
244 		// ^(101 ^(102 103 ^(106 107) ) 104 105)
245 		// stream has 7 real + 6 nav nodes
246 		// Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
247 		Tree r0 = new CommonTree(new CommonToken(101));
248 		Tree r1 = new CommonTree(new CommonToken(102));
249 		r0.addChild(r1);
250 		r1.addChild(new CommonTree(new CommonToken(103)));
251 		Tree r2 = new CommonTree(new CommonToken(106));
252 		r2.addChild(new CommonTree(new CommonToken(107)));
253 		r1.addChild(r2);
254 		r0.addChild(new CommonTree(new CommonToken(104)));
255 		r0.addChild(new CommonTree(new CommonToken(105)));
256 
257 		TreeNodeStream stream = newStream(r0);
258 		int m = stream.mark(); // MARK at start
259 		stream.consume(); // consume 101
260 		stream.consume(); // consume DN
261 		int m2 = stream.mark(); // MARK on 102
262 		stream.consume(); // consume 102
263 		stream.consume(); // consume DN
264 		stream.consume(); // consume 103
265 		stream.consume(); // consume 106
266 		stream.rewind(m2);      // REWIND to 102
267 		assertEquals(102, ((Tree)stream.LT(1)).getType());
268 		stream.consume();
269 		assertEquals(Token.DOWN, ((Tree)stream.LT(1)).getType());
270 		stream.consume();
271 		// stop at 103 and rewind to start
272 		stream.rewind(m); // REWIND to 101
273 		assertEquals(101, ((Tree)stream.LT(1)).getType());
274 		stream.consume();
275 		assertEquals(Token.DOWN, ((Tree)stream.LT(1)).getType());
276 		stream.consume();
277 		assertEquals(102, ((Tree)stream.LT(1)).getType());
278 		stream.consume();
279 		assertEquals(Token.DOWN, ((Tree)stream.LT(1)).getType());
280 	}
281 
testSeekFromStart()282 	@Test public void testSeekFromStart() throws Exception {
283 		// ^(101 ^(102 103 ^(106 107) ) 104 105)
284 		// stream has 7 real + 6 nav nodes
285 		// Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
286 		Tree r0 = new CommonTree(new CommonToken(101));
287 		Tree r1 = new CommonTree(new CommonToken(102));
288 		r0.addChild(r1);
289 		r1.addChild(new CommonTree(new CommonToken(103)));
290 		Tree r2 = new CommonTree(new CommonToken(106));
291 		r2.addChild(new CommonTree(new CommonToken(107)));
292 		r1.addChild(r2);
293 		r0.addChild(new CommonTree(new CommonToken(104)));
294 		r0.addChild(new CommonTree(new CommonToken(105)));
295 
296 		TreeNodeStream stream = newStream(r0);
297 		stream.seek(7);   // seek to 107
298 		assertEquals(107, ((Tree)stream.LT(1)).getType());
299 		stream.consume(); // consume 107
300 		stream.consume(); // consume UP
301 		stream.consume(); // consume UP
302 		assertEquals(104, ((Tree)stream.LT(1)).getType());
303 	}
304 
testReset()305     @Test public void testReset() throws Exception {
306         // ^(101 ^(102 103 ^(106 107) ) 104 105)
307         // stream has 7 real + 6 nav nodes
308         // Sequence of types: 101 DN 102 DN 103 106 DN 107 UP UP 104 105 UP EOF
309         Tree r0 = new CommonTree(new CommonToken(101));
310         Tree r1 = new CommonTree(new CommonToken(102));
311         r0.addChild(r1);
312         r1.addChild(new CommonTree(new CommonToken(103)));
313         Tree r2 = new CommonTree(new CommonToken(106));
314         r2.addChild(new CommonTree(new CommonToken(107)));
315         r1.addChild(r2);
316         r0.addChild(new CommonTree(new CommonToken(104)));
317         r0.addChild(new CommonTree(new CommonToken(105)));
318 
319         TreeNodeStream stream = newStream(r0);
320         String v = toNodesOnlyString(stream); // scan all
321         stream.reset();
322         String v2 = toNodesOnlyString(stream); // scan all
323         assertEquals(v, v2);
324     }
325 
testDeepTree()326 	@Test public void testDeepTree() throws Exception {
327 		// ^(10 100 101 ^(20 ^(30 40 (50 (60 70)))) (80 90)))
328 		// stream has 8 real + 10 nav nodes
329 		int n = 9;
330 		CommonTree[] nodes = new CommonTree[n];
331 		for (int i=0; i< n; i++) {
332 			nodes[i] = new CommonTree(new CommonToken((i+1)*10));
333 		}
334 		Tree g = nodes[0];
335 		Tree rules = nodes[1];
336 		Tree rule1 = nodes[2];
337 		Tree id = nodes[3];
338 		Tree block = nodes[4];
339 		Tree alt = nodes[5];
340 		Tree s = nodes[6];
341 		Tree rule2 = nodes[7];
342 		Tree id2 = nodes[8];
343 		g.addChild(new CommonTree(new CommonToken(100)));
344 		g.addChild(new CommonTree(new CommonToken(101)));
345 		g.addChild(rules);
346 		rules.addChild(rule1);
347 		rule1.addChild(id);
348 		rule1.addChild(block);
349 		block.addChild(alt);
350 		alt.addChild(s);
351 		rules.addChild(rule2);
352 		rule2.addChild(id2);
353 
354 		TreeNodeStream stream = newStream(g);
355 		String expecting = " 10 2 100 101 20 2 30 2 40 50 2 60 2 70 3 3 3 80 2 90 3 3 3";
356 		String found = toTokenTypeString(stream);
357 		assertEquals(expecting, found);
358 	}
359 
toNodesOnlyString(TreeNodeStream nodes)360 	public String toNodesOnlyString(TreeNodeStream nodes) {
361         TreeAdaptor adaptor = nodes.getTreeAdaptor();
362 		StringBuffer buf = new StringBuffer();
363         Object o = nodes.LT(1);
364         int type = adaptor.getType(o);
365         while ( o!=null && type!=Token.EOF ) {
366 			if ( !(type==Token.DOWN||type==Token.UP) ) {
367 				buf.append(" ");
368 				buf.append(type);
369 			}
370             nodes.consume();
371             o = nodes.LT(1);
372             type = adaptor.getType(o);
373 		}
374 		return buf.toString();
375 	}
376 }
377