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.CommonTree;
     33 import org.antlr.runtime.tree.CommonTreeAdaptor;
     34 import org.antlr.runtime.tree.Tree;
     35 import org.antlr.runtime.tree.TreeAdaptor;
     36 import org.junit.Test;
     37 
     38 public class TestTrees extends BaseTest {
     39 	TreeAdaptor adaptor = new CommonTreeAdaptor();
     40 	protected boolean debug = false;
     41 
     42 	static class V extends CommonTree {
     43 		public int x;
     44 		public V(Token t) { this.token = t;}
     45 		public V(int ttype, int x) { this.x=x; token=new CommonToken(ttype); }
     46 		public V(int ttype, Token t, int x) { token=t; this.x=x;}
     47 		public String toString() { return (token!=null?token.getText():"")+"<V>";}
     48 	}
     49 
     50 	@Test public void testSingleNode() throws Exception {
     51 		CommonTree t = new CommonTree(new CommonToken(101));
     52 		assertNull(t.parent);
     53 		assertEquals(-1, t.childIndex);
     54 	}
     55 
     56 	@Test public void testTwoChildrenOfNilRoot() throws Exception {
     57 		CommonTree root_0 = (CommonTree)adaptor.nil();
     58 		CommonTree t = new V(101, 2);
     59 		CommonTree u = new V(new CommonToken(102,"102"));
     60 		adaptor.addChild(root_0, t);
     61 		adaptor.addChild(root_0, u);
     62 		assertNull(root_0.parent);
     63 		assertEquals(-1, root_0.childIndex);
     64 		assertEquals(0, t.childIndex);
     65 		assertEquals(1, u.childIndex);
     66 	}
     67 
     68 	@Test public void test4Nodes() throws Exception {
     69 		// ^(101 ^(102 103) 104)
     70 		CommonTree r0 = new CommonTree(new CommonToken(101));
     71 		r0.addChild(new CommonTree(new CommonToken(102)));
     72 		r0.getChild(0).addChild(new CommonTree(new CommonToken(103)));
     73 		r0.addChild(new CommonTree(new CommonToken(104)));
     74 
     75 		assertNull(r0.parent);
     76 		assertEquals(-1, r0.childIndex);
     77 	}
     78 
     79 	@Test public void testList() throws Exception {
     80 		// ^(nil 101 102 103)
     81 		CommonTree r0 = new CommonTree((Token)null);
     82 		CommonTree c0, c1, c2;
     83 		r0.addChild(c0=new CommonTree(new CommonToken(101)));
     84 		r0.addChild(c1=new CommonTree(new CommonToken(102)));
     85 		r0.addChild(c2=new CommonTree(new CommonToken(103)));
     86 
     87 		assertNull(r0.parent);
     88 		assertEquals(-1, r0.childIndex);
     89 		assertEquals(r0, c0.parent);
     90 		assertEquals(0, c0.childIndex);
     91 		assertEquals(r0, c1.parent);
     92 		assertEquals(1, c1.childIndex);
     93 		assertEquals(r0, c2.parent);
     94 		assertEquals(2, c2.childIndex);
     95 	}
     96 
     97 	@Test public void testList2() throws Exception {
     98 		// Add child ^(nil 101 102 103) to root 5
     99 		// should pull 101 102 103 directly to become 5's child list
    100 		CommonTree root = new CommonTree(new CommonToken(5));
    101 
    102 		// child tree
    103 		CommonTree r0 = new CommonTree((Token)null);
    104 		CommonTree c0, c1, c2;
    105 		r0.addChild(c0=new CommonTree(new CommonToken(101)));
    106 		r0.addChild(c1=new CommonTree(new CommonToken(102)));
    107 		r0.addChild(c2=new CommonTree(new CommonToken(103)));
    108 
    109 		root.addChild(r0);
    110 
    111 		assertNull(root.parent);
    112 		assertEquals(-1, root.childIndex);
    113 		// check children of root all point at root
    114 		assertEquals(root, c0.parent);
    115 		assertEquals(0, c0.childIndex);
    116 		assertEquals(root, c0.parent);
    117 		assertEquals(1, c1.childIndex);
    118 		assertEquals(root, c0.parent);
    119 		assertEquals(2, c2.childIndex);
    120 	}
    121 
    122 	@Test public void testAddListToExistChildren() throws Exception {
    123 		// Add child ^(nil 101 102 103) to root ^(5 6)
    124 		// should add 101 102 103 to end of 5's child list
    125 		CommonTree root = new CommonTree(new CommonToken(5));
    126 		root.addChild(new CommonTree(new CommonToken(6)));
    127 
    128 		// child tree
    129 		CommonTree r0 = new CommonTree((Token)null);
    130 		CommonTree c0, c1, c2;
    131 		r0.addChild(c0=new CommonTree(new CommonToken(101)));
    132 		r0.addChild(c1=new CommonTree(new CommonToken(102)));
    133 		r0.addChild(c2=new CommonTree(new CommonToken(103)));
    134 
    135 		root.addChild(r0);
    136 
    137 		assertNull(root.parent);
    138 		assertEquals(-1, root.childIndex);
    139 		// check children of root all point at root
    140 		assertEquals(root, c0.parent);
    141 		assertEquals(1, c0.childIndex);
    142 		assertEquals(root, c0.parent);
    143 		assertEquals(2, c1.childIndex);
    144 		assertEquals(root, c0.parent);
    145 		assertEquals(3, c2.childIndex);
    146 	}
    147 
    148 	@Test public void testDupTree() throws Exception {
    149 		// ^(101 ^(102 103 ^(106 107) ) 104 105)
    150 		CommonTree r0 = new CommonTree(new CommonToken(101));
    151 		CommonTree r1 = new CommonTree(new CommonToken(102));
    152 		r0.addChild(r1);
    153 		r1.addChild(new CommonTree(new CommonToken(103)));
    154 		Tree r2 = new CommonTree(new CommonToken(106));
    155 		r2.addChild(new CommonTree(new CommonToken(107)));
    156 		r1.addChild(r2);
    157 		r0.addChild(new CommonTree(new CommonToken(104)));
    158 		r0.addChild(new CommonTree(new CommonToken(105)));
    159 
    160 		CommonTree dup = (CommonTree)(new CommonTreeAdaptor()).dupTree(r0);
    161 
    162 		assertNull(dup.parent);
    163 		assertEquals(-1, dup.childIndex);
    164 		dup.sanityCheckParentAndChildIndexes();
    165 	}
    166 
    167 	@Test public void testBecomeRoot() throws Exception {
    168 		// 5 becomes new root of ^(nil 101 102 103)
    169 		CommonTree newRoot = new CommonTree(new CommonToken(5));
    170 
    171 		CommonTree oldRoot = new CommonTree((Token)null);
    172 		oldRoot.addChild(new CommonTree(new CommonToken(101)));
    173 		oldRoot.addChild(new CommonTree(new CommonToken(102)));
    174 		oldRoot.addChild(new CommonTree(new CommonToken(103)));
    175 
    176 		TreeAdaptor adaptor = new CommonTreeAdaptor();
    177 		adaptor.becomeRoot(newRoot, oldRoot);
    178 		newRoot.sanityCheckParentAndChildIndexes();
    179 	}
    180 
    181 	@Test public void testBecomeRoot2() throws Exception {
    182 		// 5 becomes new root of ^(101 102 103)
    183 		CommonTree newRoot = new CommonTree(new CommonToken(5));
    184 
    185 		CommonTree oldRoot = new CommonTree(new CommonToken(101));
    186 		oldRoot.addChild(new CommonTree(new CommonToken(102)));
    187 		oldRoot.addChild(new CommonTree(new CommonToken(103)));
    188 
    189 		TreeAdaptor adaptor = new CommonTreeAdaptor();
    190 		adaptor.becomeRoot(newRoot, oldRoot);
    191 		newRoot.sanityCheckParentAndChildIndexes();
    192 	}
    193 
    194 	@Test public void testBecomeRoot3() throws Exception {
    195 		// ^(nil 5) becomes new root of ^(nil 101 102 103)
    196 		CommonTree newRoot = new CommonTree((Token)null);
    197 		newRoot.addChild(new CommonTree(new CommonToken(5)));
    198 
    199 		CommonTree oldRoot = new CommonTree((Token)null);
    200 		oldRoot.addChild(new CommonTree(new CommonToken(101)));
    201 		oldRoot.addChild(new CommonTree(new CommonToken(102)));
    202 		oldRoot.addChild(new CommonTree(new CommonToken(103)));
    203 
    204 		TreeAdaptor adaptor = new CommonTreeAdaptor();
    205 		adaptor.becomeRoot(newRoot, oldRoot);
    206 		newRoot.sanityCheckParentAndChildIndexes();
    207 	}
    208 
    209 	@Test public void testBecomeRoot5() throws Exception {
    210 		// ^(nil 5) becomes new root of ^(101 102 103)
    211 		CommonTree newRoot = new CommonTree((Token)null);
    212 		newRoot.addChild(new CommonTree(new CommonToken(5)));
    213 
    214 		CommonTree oldRoot = new CommonTree(new CommonToken(101));
    215 		oldRoot.addChild(new CommonTree(new CommonToken(102)));
    216 		oldRoot.addChild(new CommonTree(new CommonToken(103)));
    217 
    218 		TreeAdaptor adaptor = new CommonTreeAdaptor();
    219 		adaptor.becomeRoot(newRoot, oldRoot);
    220 		newRoot.sanityCheckParentAndChildIndexes();
    221 	}
    222 
    223 	@Test public void testBecomeRoot6() throws Exception {
    224 		// emulates construction of ^(5 6)
    225 		CommonTree root_0 = (CommonTree)adaptor.nil();
    226 		CommonTree root_1 = (CommonTree)adaptor.nil();
    227 		root_1 = (CommonTree)adaptor.becomeRoot(new CommonTree(new CommonToken(5)), root_1);
    228 
    229 		adaptor.addChild(root_1, new CommonTree(new CommonToken(6)));
    230 
    231 		adaptor.addChild(root_0, root_1);
    232 
    233 		root_0.sanityCheckParentAndChildIndexes();
    234 	}
    235 
    236 	// Test replaceChildren
    237 
    238 	@Test public void testReplaceWithNoChildren() throws Exception {
    239 		CommonTree t = new CommonTree(new CommonToken(101));
    240 		CommonTree newChild = new CommonTree(new CommonToken(5));
    241 		boolean error = false;
    242 		try {
    243 			t.replaceChildren(0, 0, newChild);
    244 		}
    245 		catch (IllegalArgumentException iae) {
    246 			error = true;
    247 		}
    248 		assertTrue(error);
    249 	}
    250 
    251 	@Test public void testReplaceWithOneChildren() throws Exception {
    252 		// assume token type 99 and use text
    253 		CommonTree t = new CommonTree(new CommonToken(99,"a"));
    254 		CommonTree c0 = new CommonTree(new CommonToken(99, "b"));
    255 		t.addChild(c0);
    256 
    257 		CommonTree newChild = new CommonTree(new CommonToken(99, "c"));
    258 		t.replaceChildren(0, 0, newChild);
    259 		String expecting = "(a c)";
    260 		assertEquals(expecting, t.toStringTree());
    261 		t.sanityCheckParentAndChildIndexes();
    262 	}
    263 
    264 	@Test public void testReplaceInMiddle() throws Exception {
    265 		CommonTree t = new CommonTree(new CommonToken(99, "a"));
    266 		t.addChild(new CommonTree(new CommonToken(99, "b")));
    267 		t.addChild(new CommonTree(new CommonToken(99, "c"))); // index 1
    268 		t.addChild(new CommonTree(new CommonToken(99, "d")));
    269 
    270 		CommonTree newChild = new CommonTree(new CommonToken(99,"x"));
    271 		t.replaceChildren(1, 1, newChild);
    272 		String expecting = "(a b x d)";
    273 		assertEquals(expecting, t.toStringTree());
    274 		t.sanityCheckParentAndChildIndexes();
    275 	}
    276 
    277 	@Test public void testReplaceAtLeft() throws Exception {
    278 		CommonTree t = new CommonTree(new CommonToken(99, "a"));
    279 		t.addChild(new CommonTree(new CommonToken(99, "b"))); // index 0
    280 		t.addChild(new CommonTree(new CommonToken(99, "c")));
    281 		t.addChild(new CommonTree(new CommonToken(99, "d")));
    282 
    283 		CommonTree newChild = new CommonTree(new CommonToken(99,"x"));
    284 		t.replaceChildren(0, 0, newChild);
    285 		String expecting = "(a x c d)";
    286 		assertEquals(expecting, t.toStringTree());
    287 		t.sanityCheckParentAndChildIndexes();
    288 	}
    289 
    290 	@Test public void testReplaceAtRight() throws Exception {
    291 		CommonTree t = new CommonTree(new CommonToken(99, "a"));
    292 		t.addChild(new CommonTree(new CommonToken(99, "b")));
    293 		t.addChild(new CommonTree(new CommonToken(99, "c")));
    294 		t.addChild(new CommonTree(new CommonToken(99, "d"))); // index 2
    295 
    296 		CommonTree newChild = new CommonTree(new CommonToken(99,"x"));
    297 		t.replaceChildren(2, 2, newChild);
    298 		String expecting = "(a b c x)";
    299 		assertEquals(expecting, t.toStringTree());
    300 		t.sanityCheckParentAndChildIndexes();
    301 	}
    302 
    303 	@Test public void testReplaceOneWithTwoAtLeft() throws Exception {
    304 		CommonTree t = new CommonTree(new CommonToken(99, "a"));
    305 		t.addChild(new CommonTree(new CommonToken(99, "b")));
    306 		t.addChild(new CommonTree(new CommonToken(99, "c")));
    307 		t.addChild(new CommonTree(new CommonToken(99, "d")));
    308 
    309 		CommonTree newChildren = (CommonTree)adaptor.nil();
    310 		newChildren.addChild(new CommonTree(new CommonToken(99,"x")));
    311 		newChildren.addChild(new CommonTree(new CommonToken(99,"y")));
    312 
    313 		t.replaceChildren(0, 0, newChildren);
    314 		String expecting = "(a x y c d)";
    315 		assertEquals(expecting, t.toStringTree());
    316 		t.sanityCheckParentAndChildIndexes();
    317 	}
    318 
    319 	@Test public void testReplaceOneWithTwoAtRight() throws Exception {
    320 		CommonTree t = new CommonTree(new CommonToken(99, "a"));
    321 		t.addChild(new CommonTree(new CommonToken(99, "b")));
    322 		t.addChild(new CommonTree(new CommonToken(99, "c")));
    323 		t.addChild(new CommonTree(new CommonToken(99, "d")));
    324 
    325 		CommonTree newChildren = (CommonTree)adaptor.nil();
    326 		newChildren.addChild(new CommonTree(new CommonToken(99,"x")));
    327 		newChildren.addChild(new CommonTree(new CommonToken(99,"y")));
    328 
    329 		t.replaceChildren(2, 2, newChildren);
    330 		String expecting = "(a b c x y)";
    331 		assertEquals(expecting, t.toStringTree());
    332 		t.sanityCheckParentAndChildIndexes();
    333 	}
    334 
    335 	@Test public void testReplaceOneWithTwoInMiddle() throws Exception {
    336 		CommonTree t = new CommonTree(new CommonToken(99, "a"));
    337 		t.addChild(new CommonTree(new CommonToken(99, "b")));
    338 		t.addChild(new CommonTree(new CommonToken(99, "c")));
    339 		t.addChild(new CommonTree(new CommonToken(99, "d")));
    340 
    341 		CommonTree newChildren = (CommonTree)adaptor.nil();
    342 		newChildren.addChild(new CommonTree(new CommonToken(99,"x")));
    343 		newChildren.addChild(new CommonTree(new CommonToken(99,"y")));
    344 
    345 		t.replaceChildren(1, 1, newChildren);
    346 		String expecting = "(a b x y d)";
    347 		assertEquals(expecting, t.toStringTree());
    348 		t.sanityCheckParentAndChildIndexes();
    349 	}
    350 
    351 	@Test public void testReplaceTwoWithOneAtLeft() throws Exception {
    352 		CommonTree t = new CommonTree(new CommonToken(99, "a"));
    353 		t.addChild(new CommonTree(new CommonToken(99, "b")));
    354 		t.addChild(new CommonTree(new CommonToken(99, "c")));
    355 		t.addChild(new CommonTree(new CommonToken(99, "d")));
    356 
    357 		CommonTree newChild = new CommonTree(new CommonToken(99,"x"));
    358 
    359 		t.replaceChildren(0, 1, newChild);
    360 		String expecting = "(a x d)";
    361 		assertEquals(expecting, t.toStringTree());
    362 		t.sanityCheckParentAndChildIndexes();
    363 	}
    364 
    365 	@Test public void testReplaceTwoWithOneAtRight() throws Exception {
    366 		CommonTree t = new CommonTree(new CommonToken(99, "a"));
    367 		t.addChild(new CommonTree(new CommonToken(99, "b")));
    368 		t.addChild(new CommonTree(new CommonToken(99, "c")));
    369 		t.addChild(new CommonTree(new CommonToken(99, "d")));
    370 
    371 		CommonTree newChild = new CommonTree(new CommonToken(99,"x"));
    372 
    373 		t.replaceChildren(1, 2, newChild);
    374 		String expecting = "(a b x)";
    375 		assertEquals(expecting, t.toStringTree());
    376 		t.sanityCheckParentAndChildIndexes();
    377 	}
    378 
    379 	@Test public void testReplaceAllWithOne() throws Exception {
    380 		CommonTree t = new CommonTree(new CommonToken(99, "a"));
    381 		t.addChild(new CommonTree(new CommonToken(99, "b")));
    382 		t.addChild(new CommonTree(new CommonToken(99, "c")));
    383 		t.addChild(new CommonTree(new CommonToken(99, "d")));
    384 
    385 		CommonTree newChild = new CommonTree(new CommonToken(99,"x"));
    386 
    387 		t.replaceChildren(0, 2, newChild);
    388 		String expecting = "(a x)";
    389 		assertEquals(expecting, t.toStringTree());
    390 		t.sanityCheckParentAndChildIndexes();
    391 	}
    392 
    393 	@Test public void testReplaceAllWithTwo() throws Exception {
    394 		CommonTree t = new CommonTree(new CommonToken(99, "a"));
    395 		t.addChild(new CommonTree(new CommonToken(99, "b")));
    396 		t.addChild(new CommonTree(new CommonToken(99, "c")));
    397 		t.addChild(new CommonTree(new CommonToken(99, "d")));
    398 
    399 		CommonTree newChildren = (CommonTree)adaptor.nil();
    400 		newChildren.addChild(new CommonTree(new CommonToken(99,"x")));
    401 		newChildren.addChild(new CommonTree(new CommonToken(99,"y")));
    402 
    403 		t.replaceChildren(0, 2, newChildren);
    404 		String expecting = "(a x y)";
    405 		assertEquals(expecting, t.toStringTree());
    406 		t.sanityCheckParentAndChildIndexes();
    407 	}
    408 }
    409