Home | History | Annotate | Download | only in test
      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. */
     39 	public TreeNodeStream newStream(Object t) {
     40 		return new CommonTreeNodeStream(t);
     41 	}
     42 
     43     public String toTokenTypeString(TreeNodeStream stream) {
     44         return ((CommonTreeNodeStream)stream).toTokenTypeString();
     45     }
     46 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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