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 */
TestTokenRewriteStream()40     public TestTokenRewriteStream() {
41     }
42 
testInsertBeforeIndex0()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 
testInsertAfterLastIndex()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 
test2InsertBeforeAfterMiddleIndex()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 
testReplaceIndex0()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 
testReplaceLastIndex()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 
testReplaceMiddleIndex()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 
testToStringStartStop()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 
testToStringStartStop2()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 
test2ReplaceMiddleIndex()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 
test2ReplaceMiddleIndex1InsertBefore()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 
testReplaceThenDeleteMiddleIndex()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 
testInsertInPriorReplace()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 
testInsertThenReplaceSameIndex()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 
test2InsertMiddleIndex()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 
test2InsertThenReplaceIndex0()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 
testReplaceThenInsertBeforeLastIndex()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 
testInsertThenReplaceLastIndex()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 
testReplaceThenInsertAfterLastIndex()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 
testReplaceRangeThenInsertAtLeftEdge()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 
testReplaceRangeThenInsertAtRightEdge()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 
testReplaceRangeThenInsertAfterRightEdge()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 
testReplaceAll()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 
testReplaceSubsetThenFetch()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 
testReplaceThenReplaceSuperset()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 
testReplaceThenReplaceLowerIndexedSuperset()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 
testReplaceSingleMiddleThenOverlappingSuperset()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 
testCombineInserts()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 
testCombine3Inserts()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 
testCombineInsertOnLeftWithReplace()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 
testCombineInsertOnLeftWithDelete()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 
testDisjointInserts()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 
testOverlappingReplace()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 
testOverlappingReplace2()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 
testOverlappingReplace3()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 
testOverlappingReplace4()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 
testDropIdenticalReplace()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 
testDropPrevCoveredInsert()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 
testLeaveAloneDisjointInsert()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 
testLeaveAloneDisjointInsert2()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 
testInsertBeforeTokenThenDeleteThatToken()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