1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/*
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD license"]
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  Copyright (c) 2010 Terence Parr
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  All rights reserved.
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  Redistribution and use in source and binary forms, with or without
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  modification, are permitted provided that the following conditions
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  are met:
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  1. Redistributions of source code must retain the above copyright
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      notice, this list of conditions and the following disclaimer.
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  2. Redistributions in binary form must reproduce the above copyright
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      notice, this list of conditions and the following disclaimer in the
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      documentation and/or other materials provided with the distribution.
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  3. The name of the author may not be used to endorse or promote products
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *      derived from this software without specific prior written permission.
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpackage org.antlr.test;
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.ANTLRStringStream;
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.CharStream;
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.TokenRewriteStream;
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.tool.Grammar;
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.tool.Interpreter;
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.junit.Test;
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic class TestTokenRewriteStream extends BaseTest {
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** Public default constructor used by TestRig */
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public TestTokenRewriteStream() {
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testInsertBeforeIndex0() throws Exception {
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(0, "0");
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "0abc";
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testInsertAfterLastIndex() throws Exception {
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertAfter(2, "x");
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "abcx";
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void test2InsertBeforeAfterMiddleIndex() throws Exception {
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(1, "x");
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertAfter(1, "x");
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "axbxc";
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceIndex0() throws Exception {
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(0, "x");
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "xbc";
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceLastIndex() throws Exception {
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, "x");
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "abx";
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceMiddleIndex() throws Exception {
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, "x");
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "axc";
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testToStringStartStop() throws Exception {
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Grammar g = new Grammar(
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "lexer grammar t;\n"+
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+;\n" +
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "INT : '0'..'9'+;\n" +
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "SEMI : ';';\n" +
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "MUL : '*';\n" +
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ASSIGN : '=';\n" +
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : ' '+;\n");
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // Tokens: 0123456789
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // Input:  x = 3 * 0;
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        CharStream input = new ANTLRStringStream("x = 3 * 0;");
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Interpreter lexEngine = new Interpreter(g, input);
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tokens.fill();
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tokens.replace(4, 8, "0"); // replace 3 * 0 with 0
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String result = tokens.toOriginalString();
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String expecting = "x = 3 * 0;";
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        result = tokens.toString();
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        expecting = "x = 0;";
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        result = tokens.toString(0,9);
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        expecting = "x = 0;";
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        result = tokens.toString(4,8);
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        expecting = "0";
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void testToStringStartStop2() throws Exception {
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Grammar g = new Grammar(
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "lexer grammar t;\n"+
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ID : 'a'..'z'+;\n" +
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "INT : '0'..'9'+;\n" +
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "SEMI : ';';\n" +
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "ASSIGN : '=';\n" +
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "PLUS : '+';\n" +
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "MULT : '*';\n" +
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "WS : ' '+;\n");
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // Tokens: 012345678901234567
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // Input:  x = 3 * 0 + 2 * 0;
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        CharStream input = new ANTLRStringStream("x = 3 * 0 + 2 * 0;");
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Interpreter lexEngine = new Interpreter(g, input);
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tokens.fill();
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String result = tokens.toOriginalString();
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String expecting = "x = 3 * 0 + 2 * 0;";
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tokens.replace(4, 8, "0"); // replace 3 * 0 with 0
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        result = tokens.toString();
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        expecting = "x = 0 + 2 * 0;";
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        result = tokens.toString(0,17);
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        expecting = "x = 0 + 2 * 0;";
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        result = tokens.toString(4,8);
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        expecting = "0";
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        result = tokens.toString(0,8);
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        expecting = "x = 0";
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        result = tokens.toString(12,16);
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        expecting = "2 * 0";
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tokens.insertAfter(17, "// comment");
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        result = tokens.toString(12,18);
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        expecting = "2 * 0;// comment";
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        result = tokens.toString(0,8); // try again after insert at end
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        expecting = "x = 0";
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assertEquals(expecting, result);
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void test2ReplaceMiddleIndex() throws Exception {
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, "x");
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, "y");
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "ayc";
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test public void test2ReplaceMiddleIndex1InsertBefore() throws Exception {
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tokens.insertBefore(0, "_");
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tokens.replace(1, "x");
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, "y");
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "_ayc";
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceThenDeleteMiddleIndex() throws Exception {
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, "x");
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.delete(1);
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "ac";
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testInsertInPriorReplace() throws Exception {
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(0, 2, "x");
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(1, "0");
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Exception exc = null;
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokens.toString();
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (IllegalArgumentException iae) {
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			exc = iae;
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		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\">";
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertNotNull(exc);
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, exc.getMessage());
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testInsertThenReplaceSameIndex() throws Exception {
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(0, "0");
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(0, "x"); // supercedes insert at 0
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "0xbc";
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void test2InsertMiddleIndex() throws Exception {
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(1, "x");
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(1, "y");
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "ayxbc";
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void test2InsertThenReplaceIndex0() throws Exception {
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(0, "x");
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(0, "y");
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(0, "z");
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "yxzbc";
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceThenInsertBeforeLastIndex() throws Exception {
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, "x");
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(2, "y");
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "abyx";
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testInsertThenReplaceLastIndex() throws Exception {
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(2, "y");
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, "x");
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "abyx";
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceThenInsertAfterLastIndex() throws Exception {
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, "x");
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertAfter(2, "y");
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "abxy";
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceRangeThenInsertAtLeftEdge() throws Exception {
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcccba");
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, 4, "x");
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(2, "y");
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "abyxba";
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceRangeThenInsertAtRightEdge() throws Exception {
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcccba");
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, 4, "x");
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(4, "y"); // no effect; within range of a replace
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Exception exc = null;
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokens.toString();
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (IllegalArgumentException iae) {
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			exc = iae;
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		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\">";
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertNotNull(exc);
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, exc.getMessage());
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceRangeThenInsertAfterRightEdge() throws Exception {
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcccba");
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, 4, "x");
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertAfter(4, "y");
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "abxyba";
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceAll() throws Exception {
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcccba");
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(0, 6, "x");
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "x";
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceSubsetThenFetch() throws Exception {
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcccba");
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, 4, "xyz");
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString(0,6);
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "abxyzba";
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceThenReplaceSuperset() throws Exception {
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcccba");
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, 4, "xyz");
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(3, 5, "foo"); // overlaps, error
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Exception exc = null;
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokens.toString();
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (IllegalArgumentException iae) {
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			exc = iae;
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		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\">";
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertNotNull(exc);
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, exc.getMessage());
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceThenReplaceLowerIndexedSuperset() throws Exception {
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcccba");
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, 4, "xyz");
529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, 3, "foo"); // overlap, error
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Exception exc = null;
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokens.toString();
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (IllegalArgumentException iae) {
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			exc = iae;
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		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\">";
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertNotNull(exc);
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, exc.getMessage());
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testReplaceSingleMiddleThenOverlappingSuperset() throws Exception {
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcba");
549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, 2, "xyz");
553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(0, 3, "foo");
554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "fooa";
556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// June 2, 2008 I rewrote core of rewrite engine; just adding lots more tests here
560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testCombineInserts() throws Exception {
562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(0, "x");
572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(0, "y");
573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "yxabc";
575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testCombine3Inserts() throws Exception {
579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(1, "x");
589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(0, "y");
590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(1, "z");
591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "yazxbc";
593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testCombineInsertOnLeftWithReplace() throws Exception {
597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(0, 2, "foo");
607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(0, "z"); // combine with left edge of rewrite
608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "zfoo";
610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testCombineInsertOnLeftWithDelete() throws Exception {
614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.delete(0, 2);
624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(0, "z"); // combine with left edge of rewrite
625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "z"; // make sure combo is not znull
627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testDisjointInserts() throws Exception {
631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(1, "x");
641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(2, "y");
642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(0, "z");
643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "zaxbyc";
645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testOverlappingReplace() throws Exception {
649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcc");
655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, 2, "foo");
659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(0, 3, "bar"); // wipes prior nested replace
660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "bar";
662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testOverlappingReplace2() throws Exception {
666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcc");
672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(0, 3, "bar");
676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, 2, "foo"); // cannot split earlier replace
677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Exception exc = null;
678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokens.toString();
680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (IllegalArgumentException iae) {
682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			exc = iae;
683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		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\">";
685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertNotNull(exc);
686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, exc.getMessage());
687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testOverlappingReplace3() throws Exception {
690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcc");
696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, 2, "foo");
700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(0, 2, "bar"); // wipes prior nested replace
701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "barc";
703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testOverlappingReplace4() throws Exception {
707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcc");
713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, 2, "foo");
717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, 3, "bar"); // wipes prior nested replace
718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "abar";
720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testDropIdenticalReplace() throws Exception {
724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcc");
730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, 2, "foo");
734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, 2, "foo"); // drop previous, identical
735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "afooc";
737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testDropPrevCoveredInsert() throws Exception {
741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(1, "foo");
751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(1, 2, "foo"); // kill prev insert
752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "afoofoo";
754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testLeaveAloneDisjointInsert() throws Exception {
758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcc");
764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(1, "x");
768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, 3, "foo");
769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "axbfoo";
771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testLeaveAloneDisjointInsert2() throws Exception {
775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abcc");
781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.replace(2, 3, "foo");
785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(1, "x");
786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "axbfoo";
788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testInsertBeforeTokenThenDeleteThatToken() throws Exception {
792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar t;\n"+
794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : 'a';\n" +
795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'b';\n" +
796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : 'c';\n");
797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CharStream input = new ANTLRStringStream("abc");
798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Interpreter lexEngine = new Interpreter(g, input);
799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TokenRewriteStream tokens = new TokenRewriteStream(lexEngine);
800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.fill();
801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.insertBefore(2, "y");
802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokens.delete(2);
803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = tokens.toString();
804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting = "aby";
805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
809