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.ANTLRStringStream;
     31 import org.antlr.runtime.CharStream;
     32 import org.antlr.runtime.TokenRewriteStream;
     33 import org.antlr.tool.Grammar;
     34 import org.antlr.tool.Interpreter;
     35 import org.junit.Test;
     36 
     37 public class TestTokenRewriteStream extends BaseTest {
     38 
     39     /** Public default constructor used by TestRig */
     40     public TestTokenRewriteStream() {
     41     }
     42 
     43 	@Test public void testInsertBeforeIndex0() throws Exception {
     44 		Grammar g = new Grammar(
     45 			"lexer grammar t;\n"+
     46 			"A : 'a';\n" +
     47 			"B : 'b';\n" +
     48 			"C : 'c';\n");
     49 		CharStream input = new ANTLRStringStream("abc");
     50 		Interpreter lexEngine = new Interpreter(g, input);
     51 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
     52 		tokens.insertBefore(0, "0");
     53 		String result = tokens.toString();
     54 		String expecting = "0abc";
     55 		assertEquals(expecting, result);
     56 	}
     57 
     58 	@Test public void testInsertAfterLastIndex() throws Exception {
     59 		Grammar g = new Grammar(
     60 			"lexer grammar t;\n"+
     61 			"A : 'a';\n" +
     62 			"B : 'b';\n" +
     63 			"C : 'c';\n");
     64 		CharStream input = new ANTLRStringStream("abc");
     65 		Interpreter lexEngine = new Interpreter(g, input);
     66 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
     67 		tokens.insertAfter(2, "x");
     68 		String result = tokens.toString();
     69 		String expecting = "abcx";
     70 		assertEquals(expecting, result);
     71 	}
     72 
     73 	@Test public void test2InsertBeforeAfterMiddleIndex() throws Exception {
     74 		Grammar g = new Grammar(
     75 			"lexer grammar t;\n"+
     76 			"A : 'a';\n" +
     77 			"B : 'b';\n" +
     78 			"C : 'c';\n");
     79 		CharStream input = new ANTLRStringStream("abc");
     80 		Interpreter lexEngine = new Interpreter(g, input);
     81 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
     82 		tokens.fill();
     83 		tokens.insertBefore(1, "x");
     84 		tokens.insertAfter(1, "x");
     85 		String result = tokens.toString();
     86 		String expecting = "axbxc";
     87 		assertEquals(expecting, result);
     88 	}
     89 
     90 	@Test public void testReplaceIndex0() throws Exception {
     91 		Grammar g = new Grammar(
     92 			"lexer grammar t;\n"+
     93 			"A : 'a';\n" +
     94 			"B : 'b';\n" +
     95 			"C : 'c';\n");
     96 		CharStream input = new ANTLRStringStream("abc");
     97 		Interpreter lexEngine = new Interpreter(g, input);
     98 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
     99 		tokens.fill();
    100 		tokens.replace(0, "x");
    101 		String result = tokens.toString();
    102 		String expecting = "xbc";
    103 		assertEquals(expecting, result);
    104 	}
    105 
    106 	@Test public void testReplaceLastIndex() throws Exception {
    107 		Grammar g = new Grammar(
    108 			"lexer grammar t;\n"+
    109 			"A : 'a';\n" +
    110 			"B : 'b';\n" +
    111 			"C : 'c';\n");
    112 		CharStream input = new ANTLRStringStream("abc");
    113 		Interpreter lexEngine = new Interpreter(g, input);
    114 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    115 		tokens.fill();
    116 		tokens.replace(2, "x");
    117 		String result = tokens.toString();
    118 		String expecting = "abx";
    119 		assertEquals(expecting, result);
    120 	}
    121 
    122 	@Test public void testReplaceMiddleIndex() throws Exception {
    123 		Grammar g = new Grammar(
    124 			"lexer grammar t;\n"+
    125 			"A : 'a';\n" +
    126 			"B : 'b';\n" +
    127 			"C : 'c';\n");
    128 		CharStream input = new ANTLRStringStream("abc");
    129 		Interpreter lexEngine = new Interpreter(g, input);
    130 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    131 		tokens.fill();
    132 		tokens.replace(1, "x");
    133 		String result = tokens.toString();
    134 		String expecting = "axc";
    135 		assertEquals(expecting, result);
    136 	}
    137 
    138     @Test public void testToStringStartStop() throws Exception {
    139         Grammar g = new Grammar(
    140             "lexer grammar t;\n"+
    141             "ID : 'a'..'z'+;\n" +
    142             "INT : '0'..'9'+;\n" +
    143             "SEMI : ';';\n" +
    144             "MUL : '*';\n" +
    145             "ASSIGN : '=';\n" +
    146             "WS : ' '+;\n");
    147         // Tokens: 0123456789
    148         // Input:  x = 3 * 0;
    149         CharStream input = new ANTLRStringStream("x = 3 * 0;");
    150         Interpreter lexEngine = new Interpreter(g, input);
    151         TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    152         tokens.fill();
    153         tokens.replace(4, 8, "0"); // replace 3 * 0 with 0
    154 
    155         String result = tokens.toOriginalString();
    156         String expecting = "x = 3 * 0;";
    157         assertEquals(expecting, result);
    158 
    159         result = tokens.toString();
    160         expecting = "x = 0;";
    161         assertEquals(expecting, result);
    162 
    163         result = tokens.toString(0,9);
    164         expecting = "x = 0;";
    165         assertEquals(expecting, result);
    166 
    167         result = tokens.toString(4,8);
    168         expecting = "0";
    169         assertEquals(expecting, result);
    170     }
    171 
    172     @Test public void testToStringStartStop2() throws Exception {
    173         Grammar g = new Grammar(
    174             "lexer grammar t;\n"+
    175             "ID : 'a'..'z'+;\n" +
    176             "INT : '0'..'9'+;\n" +
    177             "SEMI : ';';\n" +
    178             "ASSIGN : '=';\n" +
    179             "PLUS : '+';\n" +
    180             "MULT : '*';\n" +
    181             "WS : ' '+;\n");
    182         // Tokens: 012345678901234567
    183         // Input:  x = 3 * 0 + 2 * 0;
    184         CharStream input = new ANTLRStringStream("x = 3 * 0 + 2 * 0;");
    185         Interpreter lexEngine = new Interpreter(g, input);
    186         TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    187         tokens.fill();
    188 
    189         String result = tokens.toOriginalString();
    190         String expecting = "x = 3 * 0 + 2 * 0;";
    191         assertEquals(expecting, result);
    192 
    193         tokens.replace(4, 8, "0"); // replace 3 * 0 with 0
    194         result = tokens.toString();
    195         expecting = "x = 0 + 2 * 0;";
    196         assertEquals(expecting, result);
    197 
    198         result = tokens.toString(0,17);
    199         expecting = "x = 0 + 2 * 0;";
    200         assertEquals(expecting, result);
    201 
    202         result = tokens.toString(4,8);
    203         expecting = "0";
    204         assertEquals(expecting, result);
    205 
    206         result = tokens.toString(0,8);
    207         expecting = "x = 0";
    208         assertEquals(expecting, result);
    209 
    210         result = tokens.toString(12,16);
    211         expecting = "2 * 0";
    212         assertEquals(expecting, result);
    213 
    214         tokens.insertAfter(17, "// comment");
    215         result = tokens.toString(12,18);
    216         expecting = "2 * 0;// comment";
    217         assertEquals(expecting, result);
    218 
    219         result = tokens.toString(0,8); // try again after insert at end
    220         expecting = "x = 0";
    221         assertEquals(expecting, result);
    222     }
    223 
    224 
    225     @Test public void test2ReplaceMiddleIndex() throws Exception {
    226 		Grammar g = new Grammar(
    227 			"lexer grammar t;\n"+
    228 			"A : 'a';\n" +
    229 			"B : 'b';\n" +
    230 			"C : 'c';\n");
    231 		CharStream input = new ANTLRStringStream("abc");
    232 		Interpreter lexEngine = new Interpreter(g, input);
    233 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    234 		tokens.fill();
    235 		tokens.replace(1, "x");
    236 		tokens.replace(1, "y");
    237 		String result = tokens.toString();
    238 		String expecting = "ayc";
    239 		assertEquals(expecting, result);
    240 	}
    241 
    242     @Test public void test2ReplaceMiddleIndex1InsertBefore() throws Exception {
    243 		Grammar g = new Grammar(
    244 			"lexer grammar t;\n"+
    245 			"A : 'a';\n" +
    246 			"B : 'b';\n" +
    247 			"C : 'c';\n");
    248 		CharStream input = new ANTLRStringStream("abc");
    249 		Interpreter lexEngine = new Interpreter(g, input);
    250 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    251 		tokens.fill();
    252         tokens.insertBefore(0, "_");
    253         tokens.replace(1, "x");
    254 		tokens.replace(1, "y");
    255 		String result = tokens.toString();
    256 		String expecting = "_ayc";
    257 		assertEquals(expecting, result);
    258 	}
    259 
    260 	@Test public void testReplaceThenDeleteMiddleIndex() throws Exception {
    261 		Grammar g = new Grammar(
    262 			"lexer grammar t;\n"+
    263 			"A : 'a';\n" +
    264 			"B : 'b';\n" +
    265 			"C : 'c';\n");
    266 		CharStream input = new ANTLRStringStream("abc");
    267 		Interpreter lexEngine = new Interpreter(g, input);
    268 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    269 		tokens.fill();
    270 		tokens.replace(1, "x");
    271 		tokens.delete(1);
    272 		String result = tokens.toString();
    273 		String expecting = "ac";
    274 		assertEquals(expecting, result);
    275 	}
    276 
    277 	@Test public void testInsertInPriorReplace() throws Exception {
    278 		Grammar g = new Grammar(
    279 			"lexer grammar t;\n"+
    280 			"A : 'a';\n" +
    281 			"B : 'b';\n" +
    282 			"C : 'c';\n");
    283 		CharStream input = new ANTLRStringStream("abc");
    284 		Interpreter lexEngine = new Interpreter(g, input);
    285 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    286 		tokens.fill();
    287 		tokens.replace(0, 2, "x");
    288 		tokens.insertBefore(1, "0");
    289 		Exception exc = null;
    290 		try {
    291 			tokens.toString();
    292 		}
    293 		catch (IllegalArgumentException iae) {
    294 			exc = iae;
    295 		}
    296 		String expecting = "insert op <InsertBeforeOp@[@1,1:1='b',<5>,1:1]:\"0\"> within boundaries of previous <ReplaceOp@[@0,0:0='a',<4>,1:0]..[@2,2:2='c',<6>,1:2]:\"x\">";
    297 		assertNotNull(exc);
    298 		assertEquals(expecting, exc.getMessage());
    299 	}
    300 
    301 	@Test public void testInsertThenReplaceSameIndex() throws Exception {
    302 		Grammar g = new Grammar(
    303 			"lexer grammar t;\n"+
    304 			"A : 'a';\n" +
    305 			"B : 'b';\n" +
    306 			"C : 'c';\n");
    307 		CharStream input = new ANTLRStringStream("abc");
    308 		Interpreter lexEngine = new Interpreter(g, input);
    309 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    310 		tokens.fill();
    311 		tokens.insertBefore(0, "0");
    312 		tokens.replace(0, "x"); // supercedes insert at 0
    313 		String result = tokens.toString();
    314 		String expecting = "0xbc";
    315 		assertEquals(expecting, result);
    316 	}
    317 
    318 	@Test public void test2InsertMiddleIndex() throws Exception {
    319 		Grammar g = new Grammar(
    320 			"lexer grammar t;\n"+
    321 			"A : 'a';\n" +
    322 			"B : 'b';\n" +
    323 			"C : 'c';\n");
    324 		CharStream input = new ANTLRStringStream("abc");
    325 		Interpreter lexEngine = new Interpreter(g, input);
    326 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    327 		tokens.fill();
    328 		tokens.insertBefore(1, "x");
    329 		tokens.insertBefore(1, "y");
    330 		String result = tokens.toString();
    331 		String expecting = "ayxbc";
    332 		assertEquals(expecting, result);
    333 	}
    334 
    335 	@Test public void test2InsertThenReplaceIndex0() throws Exception {
    336 		Grammar g = new Grammar(
    337 			"lexer grammar t;\n"+
    338 			"A : 'a';\n" +
    339 			"B : 'b';\n" +
    340 			"C : 'c';\n");
    341 		CharStream input = new ANTLRStringStream("abc");
    342 		Interpreter lexEngine = new Interpreter(g, input);
    343 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    344 		tokens.fill();
    345 		tokens.insertBefore(0, "x");
    346 		tokens.insertBefore(0, "y");
    347 		tokens.replace(0, "z");
    348 		String result = tokens.toString();
    349 		String expecting = "yxzbc";
    350 		assertEquals(expecting, result);
    351 	}
    352 
    353 	@Test public void testReplaceThenInsertBeforeLastIndex() throws Exception {
    354 		Grammar g = new Grammar(
    355 			"lexer grammar t;\n"+
    356 			"A : 'a';\n" +
    357 			"B : 'b';\n" +
    358 			"C : 'c';\n");
    359 		CharStream input = new ANTLRStringStream("abc");
    360 		Interpreter lexEngine = new Interpreter(g, input);
    361 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    362 		tokens.fill();
    363 		tokens.replace(2, "x");
    364 		tokens.insertBefore(2, "y");
    365 		String result = tokens.toString();
    366 		String expecting = "abyx";
    367 		assertEquals(expecting, result);
    368 	}
    369 
    370 	@Test public void testInsertThenReplaceLastIndex() throws Exception {
    371 		Grammar g = new Grammar(
    372 			"lexer grammar t;\n"+
    373 			"A : 'a';\n" +
    374 			"B : 'b';\n" +
    375 			"C : 'c';\n");
    376 		CharStream input = new ANTLRStringStream("abc");
    377 		Interpreter lexEngine = new Interpreter(g, input);
    378 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    379 		tokens.fill();
    380 		tokens.insertBefore(2, "y");
    381 		tokens.replace(2, "x");
    382 		String result = tokens.toString();
    383 		String expecting = "abyx";
    384 		assertEquals(expecting, result);
    385 	}
    386 
    387 	@Test public void testReplaceThenInsertAfterLastIndex() throws Exception {
    388 		Grammar g = new Grammar(
    389 			"lexer grammar t;\n"+
    390 			"A : 'a';\n" +
    391 			"B : 'b';\n" +
    392 			"C : 'c';\n");
    393 		CharStream input = new ANTLRStringStream("abc");
    394 		Interpreter lexEngine = new Interpreter(g, input);
    395 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    396 		tokens.fill();
    397 		tokens.replace(2, "x");
    398 		tokens.insertAfter(2, "y");
    399 		String result = tokens.toString();
    400 		String expecting = "abxy";
    401 		assertEquals(expecting, result);
    402 	}
    403 
    404 	@Test public void testReplaceRangeThenInsertAtLeftEdge() throws Exception {
    405 		Grammar g = new Grammar(
    406 			"lexer grammar t;\n"+
    407 			"A : 'a';\n" +
    408 			"B : 'b';\n" +
    409 			"C : 'c';\n");
    410 		CharStream input = new ANTLRStringStream("abcccba");
    411 		Interpreter lexEngine = new Interpreter(g, input);
    412 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    413 		tokens.fill();
    414 		tokens.replace(2, 4, "x");
    415 		tokens.insertBefore(2, "y");
    416 		String result = tokens.toString();
    417 		String expecting = "abyxba";
    418 		assertEquals(expecting, result);
    419 	}
    420 
    421 	@Test public void testReplaceRangeThenInsertAtRightEdge() throws Exception {
    422 		Grammar g = new Grammar(
    423 			"lexer grammar t;\n"+
    424 			"A : 'a';\n" +
    425 			"B : 'b';\n" +
    426 			"C : 'c';\n");
    427 		CharStream input = new ANTLRStringStream("abcccba");
    428 		Interpreter lexEngine = new Interpreter(g, input);
    429 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    430 		tokens.fill();
    431 		tokens.replace(2, 4, "x");
    432 		tokens.insertBefore(4, "y"); // no effect; within range of a replace
    433 		Exception exc = null;
    434 		try {
    435 			tokens.toString();
    436 		}
    437 		catch (IllegalArgumentException iae) {
    438 			exc = iae;
    439 		}
    440 		String expecting = "insert op <InsertBeforeOp@[@4,4:4='c',<6>,1:4]:\"y\"> within boundaries of previous <ReplaceOp@[@2,2:2='c',<6>,1:2]..[@4,4:4='c',<6>,1:4]:\"x\">";
    441 		assertNotNull(exc);
    442 		assertEquals(expecting, exc.getMessage());
    443 	}
    444 
    445 	@Test public void testReplaceRangeThenInsertAfterRightEdge() throws Exception {
    446 		Grammar g = new Grammar(
    447 			"lexer grammar t;\n"+
    448 			"A : 'a';\n" +
    449 			"B : 'b';\n" +
    450 			"C : 'c';\n");
    451 		CharStream input = new ANTLRStringStream("abcccba");
    452 		Interpreter lexEngine = new Interpreter(g, input);
    453 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    454 		tokens.fill();
    455 		tokens.replace(2, 4, "x");
    456 		tokens.insertAfter(4, "y");
    457 		String result = tokens.toString();
    458 		String expecting = "abxyba";
    459 		assertEquals(expecting, result);
    460 	}
    461 
    462 	@Test public void testReplaceAll() throws Exception {
    463 		Grammar g = new Grammar(
    464 			"lexer grammar t;\n"+
    465 			"A : 'a';\n" +
    466 			"B : 'b';\n" +
    467 			"C : 'c';\n");
    468 		CharStream input = new ANTLRStringStream("abcccba");
    469 		Interpreter lexEngine = new Interpreter(g, input);
    470 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    471 		tokens.fill();
    472 		tokens.replace(0, 6, "x");
    473 		String result = tokens.toString();
    474 		String expecting = "x";
    475 		assertEquals(expecting, result);
    476 	}
    477 
    478 	@Test public void testReplaceSubsetThenFetch() throws Exception {
    479 		Grammar g = new Grammar(
    480 			"lexer grammar t;\n"+
    481 			"A : 'a';\n" +
    482 			"B : 'b';\n" +
    483 			"C : 'c';\n");
    484 		CharStream input = new ANTLRStringStream("abcccba");
    485 		Interpreter lexEngine = new Interpreter(g, input);
    486 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    487 		tokens.fill();
    488 		tokens.replace(2, 4, "xyz");
    489 		String result = tokens.toString(0,6);
    490 		String expecting = "abxyzba";
    491 		assertEquals(expecting, result);
    492 	}
    493 
    494 	@Test public void testReplaceThenReplaceSuperset() throws Exception {
    495 		Grammar g = new Grammar(
    496 			"lexer grammar t;\n"+
    497 			"A : 'a';\n" +
    498 			"B : 'b';\n" +
    499 			"C : 'c';\n");
    500 		CharStream input = new ANTLRStringStream("abcccba");
    501 		Interpreter lexEngine = new Interpreter(g, input);
    502 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    503 		tokens.fill();
    504 		tokens.replace(2, 4, "xyz");
    505 		tokens.replace(3, 5, "foo"); // overlaps, error
    506 		Exception exc = null;
    507 		try {
    508 			tokens.toString();
    509 		}
    510 		catch (IllegalArgumentException iae) {
    511 			exc = iae;
    512 		}
    513 		String expecting = "replace op boundaries of <ReplaceOp@[@3,3:3='c',<6>,1:3]..[@5,5:5='b',<5>,1:5]:\"foo\"> overlap with previous <ReplaceOp@[@2,2:2='c',<6>,1:2]..[@4,4:4='c',<6>,1:4]:\"xyz\">";
    514 		assertNotNull(exc);
    515 		assertEquals(expecting, exc.getMessage());
    516 	}
    517 
    518 	@Test public void testReplaceThenReplaceLowerIndexedSuperset() throws Exception {
    519 		Grammar g = new Grammar(
    520 			"lexer grammar t;\n"+
    521 			"A : 'a';\n" +
    522 			"B : 'b';\n" +
    523 			"C : 'c';\n");
    524 		CharStream input = new ANTLRStringStream("abcccba");
    525 		Interpreter lexEngine = new Interpreter(g, input);
    526 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    527 		tokens.fill();
    528 		tokens.replace(2, 4, "xyz");
    529 		tokens.replace(1, 3, "foo"); // overlap, error
    530 		Exception exc = null;
    531 		try {
    532 			tokens.toString();
    533 		}
    534 		catch (IllegalArgumentException iae) {
    535 			exc = iae;
    536 		}
    537 		String expecting = "replace op boundaries of <ReplaceOp@[@1,1:1='b',<5>,1:1]..[@3,3:3='c',<6>,1:3]:\"foo\"> overlap with previous <ReplaceOp@[@2,2:2='c',<6>,1:2]..[@4,4:4='c',<6>,1:4]:\"xyz\">";
    538 		assertNotNull(exc);
    539 		assertEquals(expecting, exc.getMessage());
    540 	}
    541 
    542 	@Test public void testReplaceSingleMiddleThenOverlappingSuperset() throws Exception {
    543 		Grammar g = new Grammar(
    544 			"lexer grammar t;\n"+
    545 			"A : 'a';\n" +
    546 			"B : 'b';\n" +
    547 			"C : 'c';\n");
    548 		CharStream input = new ANTLRStringStream("abcba");
    549 		Interpreter lexEngine = new Interpreter(g, input);
    550 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    551 		tokens.fill();
    552 		tokens.replace(2, 2, "xyz");
    553 		tokens.replace(0, 3, "foo");
    554 		String result = tokens.toString();
    555 		String expecting = "fooa";
    556 		assertEquals(expecting, result);
    557 	}
    558 
    559 	// June 2, 2008 I rewrote core of rewrite engine; just adding lots more tests here
    560 
    561 	@Test public void testCombineInserts() throws Exception {
    562 		Grammar g = new Grammar(
    563 			"lexer grammar t;\n"+
    564 			"A : 'a';\n" +
    565 			"B : 'b';\n" +
    566 			"C : 'c';\n");
    567 		CharStream input = new ANTLRStringStream("abc");
    568 		Interpreter lexEngine = new Interpreter(g, input);
    569 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    570 		tokens.fill();
    571 		tokens.insertBefore(0, "x");
    572 		tokens.insertBefore(0, "y");
    573 		String result = tokens.toString();
    574 		String expecting = "yxabc";
    575 		assertEquals(expecting, result);
    576 	}
    577 
    578 	@Test public void testCombine3Inserts() throws Exception {
    579 		Grammar g = new Grammar(
    580 			"lexer grammar t;\n"+
    581 			"A : 'a';\n" +
    582 			"B : 'b';\n" +
    583 			"C : 'c';\n");
    584 		CharStream input = new ANTLRStringStream("abc");
    585 		Interpreter lexEngine = new Interpreter(g, input);
    586 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    587 		tokens.fill();
    588 		tokens.insertBefore(1, "x");
    589 		tokens.insertBefore(0, "y");
    590 		tokens.insertBefore(1, "z");
    591 		String result = tokens.toString();
    592 		String expecting = "yazxbc";
    593 		assertEquals(expecting, result);
    594 	}
    595 
    596 	@Test public void testCombineInsertOnLeftWithReplace() throws Exception {
    597 		Grammar g = new Grammar(
    598 			"lexer grammar t;\n"+
    599 			"A : 'a';\n" +
    600 			"B : 'b';\n" +
    601 			"C : 'c';\n");
    602 		CharStream input = new ANTLRStringStream("abc");
    603 		Interpreter lexEngine = new Interpreter(g, input);
    604 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    605 		tokens.fill();
    606 		tokens.replace(0, 2, "foo");
    607 		tokens.insertBefore(0, "z"); // combine with left edge of rewrite
    608 		String result = tokens.toString();
    609 		String expecting = "zfoo";
    610 		assertEquals(expecting, result);
    611 	}
    612 
    613 	@Test public void testCombineInsertOnLeftWithDelete() throws Exception {
    614 		Grammar g = new Grammar(
    615 			"lexer grammar t;\n"+
    616 			"A : 'a';\n" +
    617 			"B : 'b';\n" +
    618 			"C : 'c';\n");
    619 		CharStream input = new ANTLRStringStream("abc");
    620 		Interpreter lexEngine = new Interpreter(g, input);
    621 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    622 		tokens.fill();
    623 		tokens.delete(0, 2);
    624 		tokens.insertBefore(0, "z"); // combine with left edge of rewrite
    625 		String result = tokens.toString();
    626 		String expecting = "z"; // make sure combo is not znull
    627 		assertEquals(expecting, result);
    628 	}
    629 
    630 	@Test public void testDisjointInserts() throws Exception {
    631 		Grammar g = new Grammar(
    632 			"lexer grammar t;\n"+
    633 			"A : 'a';\n" +
    634 			"B : 'b';\n" +
    635 			"C : 'c';\n");
    636 		CharStream input = new ANTLRStringStream("abc");
    637 		Interpreter lexEngine = new Interpreter(g, input);
    638 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    639 		tokens.fill();
    640 		tokens.insertBefore(1, "x");
    641 		tokens.insertBefore(2, "y");
    642 		tokens.insertBefore(0, "z");
    643 		String result = tokens.toString();
    644 		String expecting = "zaxbyc";
    645 		assertEquals(expecting, result);
    646 	}
    647 
    648 	@Test public void testOverlappingReplace() throws Exception {
    649 		Grammar g = new Grammar(
    650 			"lexer grammar t;\n"+
    651 			"A : 'a';\n" +
    652 			"B : 'b';\n" +
    653 			"C : 'c';\n");
    654 		CharStream input = new ANTLRStringStream("abcc");
    655 		Interpreter lexEngine = new Interpreter(g, input);
    656 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    657 		tokens.fill();
    658 		tokens.replace(1, 2, "foo");
    659 		tokens.replace(0, 3, "bar"); // wipes prior nested replace
    660 		String result = tokens.toString();
    661 		String expecting = "bar";
    662 		assertEquals(expecting, result);
    663 	}
    664 
    665 	@Test public void testOverlappingReplace2() throws Exception {
    666 		Grammar g = new Grammar(
    667 			"lexer grammar t;\n"+
    668 			"A : 'a';\n" +
    669 			"B : 'b';\n" +
    670 			"C : 'c';\n");
    671 		CharStream input = new ANTLRStringStream("abcc");
    672 		Interpreter lexEngine = new Interpreter(g, input);
    673 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    674 		tokens.fill();
    675 		tokens.replace(0, 3, "bar");
    676 		tokens.replace(1, 2, "foo"); // cannot split earlier replace
    677 		Exception exc = null;
    678 		try {
    679 			tokens.toString();
    680 		}
    681 		catch (IllegalArgumentException iae) {
    682 			exc = iae;
    683 		}
    684 		String expecting = "replace op boundaries of <ReplaceOp@[@1,1:1='b',<5>,1:1]..[@2,2:2='c',<6>,1:2]:\"foo\"> overlap with previous <ReplaceOp@[@0,0:0='a',<4>,1:0]..[@3,3:3='c',<6>,1:3]:\"bar\">";
    685 		assertNotNull(exc);
    686 		assertEquals(expecting, exc.getMessage());
    687 	}
    688 
    689 	@Test public void testOverlappingReplace3() throws Exception {
    690 		Grammar g = new Grammar(
    691 			"lexer grammar t;\n"+
    692 			"A : 'a';\n" +
    693 			"B : 'b';\n" +
    694 			"C : 'c';\n");
    695 		CharStream input = new ANTLRStringStream("abcc");
    696 		Interpreter lexEngine = new Interpreter(g, input);
    697 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    698 		tokens.fill();
    699 		tokens.replace(1, 2, "foo");
    700 		tokens.replace(0, 2, "bar"); // wipes prior nested replace
    701 		String result = tokens.toString();
    702 		String expecting = "barc";
    703 		assertEquals(expecting, result);
    704 	}
    705 
    706 	@Test public void testOverlappingReplace4() throws Exception {
    707 		Grammar g = new Grammar(
    708 			"lexer grammar t;\n"+
    709 			"A : 'a';\n" +
    710 			"B : 'b';\n" +
    711 			"C : 'c';\n");
    712 		CharStream input = new ANTLRStringStream("abcc");
    713 		Interpreter lexEngine = new Interpreter(g, input);
    714 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    715 		tokens.fill();
    716 		tokens.replace(1, 2, "foo");
    717 		tokens.replace(1, 3, "bar"); // wipes prior nested replace
    718 		String result = tokens.toString();
    719 		String expecting = "abar";
    720 		assertEquals(expecting, result);
    721 	}
    722 
    723 	@Test public void testDropIdenticalReplace() throws Exception {
    724 		Grammar g = new Grammar(
    725 			"lexer grammar t;\n"+
    726 			"A : 'a';\n" +
    727 			"B : 'b';\n" +
    728 			"C : 'c';\n");
    729 		CharStream input = new ANTLRStringStream("abcc");
    730 		Interpreter lexEngine = new Interpreter(g, input);
    731 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    732 		tokens.fill();
    733 		tokens.replace(1, 2, "foo");
    734 		tokens.replace(1, 2, "foo"); // drop previous, identical
    735 		String result = tokens.toString();
    736 		String expecting = "afooc";
    737 		assertEquals(expecting, result);
    738 	}
    739 
    740 	@Test public void testDropPrevCoveredInsert() throws Exception {
    741 		Grammar g = new Grammar(
    742 			"lexer grammar t;\n"+
    743 			"A : 'a';\n" +
    744 			"B : 'b';\n" +
    745 			"C : 'c';\n");
    746 		CharStream input = new ANTLRStringStream("abc");
    747 		Interpreter lexEngine = new Interpreter(g, input);
    748 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    749 		tokens.fill();
    750 		tokens.insertBefore(1, "foo");
    751 		tokens.replace(1, 2, "foo"); // kill prev insert
    752 		String result = tokens.toString();
    753 		String expecting = "afoofoo";
    754 		assertEquals(expecting, result);
    755 	}
    756 
    757 	@Test public void testLeaveAloneDisjointInsert() throws Exception {
    758 		Grammar g = new Grammar(
    759 			"lexer grammar t;\n"+
    760 			"A : 'a';\n" +
    761 			"B : 'b';\n" +
    762 			"C : 'c';\n");
    763 		CharStream input = new ANTLRStringStream("abcc");
    764 		Interpreter lexEngine = new Interpreter(g, input);
    765 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    766 		tokens.fill();
    767 		tokens.insertBefore(1, "x");
    768 		tokens.replace(2, 3, "foo");
    769 		String result = tokens.toString();
    770 		String expecting = "axbfoo";
    771 		assertEquals(expecting, result);
    772 	}
    773 
    774 	@Test public void testLeaveAloneDisjointInsert2() throws Exception {
    775 		Grammar g = new Grammar(
    776 			"lexer grammar t;\n"+
    777 			"A : 'a';\n" +
    778 			"B : 'b';\n" +
    779 			"C : 'c';\n");
    780 		CharStream input = new ANTLRStringStream("abcc");
    781 		Interpreter lexEngine = new Interpreter(g, input);
    782 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    783 		tokens.fill();
    784 		tokens.replace(2, 3, "foo");
    785 		tokens.insertBefore(1, "x");
    786 		String result = tokens.toString();
    787 		String expecting = "axbfoo";
    788 		assertEquals(expecting, result);
    789 	}
    790 
    791 	@Test public void testInsertBeforeTokenThenDeleteThatToken() throws Exception {
    792 		Grammar g = new Grammar(
    793 			"lexer grammar t;\n"+
    794 			"A : 'a';\n" +
    795 			"B : 'b';\n" +
    796 			"C : 'c';\n");
    797 		CharStream input = new ANTLRStringStream("abc");
    798 		Interpreter lexEngine = new Interpreter(g, input);
    799 		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
    800 		tokens.fill();
    801 		tokens.insertBefore(2, "y");
    802 		tokens.delete(2);
    803 		String result = tokens.toString();
    804 		String expecting = "aby";
    805 		assertEquals(expecting, result);
    806 	}
    807 
    808 }
    809