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.analysis.DFA;
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.analysis.DecisionProbe;
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.codegen.CodeGenerator;
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.misc.BitSet;
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.Token;
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.tool.*;
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.junit.Test;
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.List;
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.Map;
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.Set;
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic class TestSemanticPredicates extends BaseTest {
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Public default constructor used by TestRig */
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public TestSemanticPredicates() {
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testPredsButSyntaxResolves() throws Exception {
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : {p1}? A | {p2}? B ;");
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->:s1=>1\n" +
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-B->:s2=>2\n";
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testLL_1_Pred() throws Exception {
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : {p1}? A | {p2}? A ;");
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p1}?->:s2=>1\n" +
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p2}?->:s3=>2\n";
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testLL_1_Pred_forced_k_1() throws Exception {
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// should stop just like before w/o k set.
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a options {k=1;} : {p1}? A | {p2}? A ;");
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p1}?->:s2=>1\n" +
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p2}?->:s3=>2\n";
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testLL_2_Pred() throws Exception {
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : {p1}? A B | {p2}? A B ;");
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-B->.s2\n" +
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{p1}?->:s3=>1\n" +
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{p2}?->:s4=>2\n";
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testPredicatedLoop() throws Exception {
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ( {p1}? A | {p2}? A )+;");
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =                   // loop back
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s2\n" +
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-EOF->:s1=>3\n" +
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{p1}?->:s3=>1\n" +
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{p2}?->:s4=>2\n";
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testPredicatedToStayInLoop() throws Exception {
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ( {p1}? A )+ (A)+;");
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p1}?->:s2=>1\n" +
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{true}?->:s3=>2\n";       // loop back
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testAndPredicates() throws Exception {
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : {p1}? {p1a}? A | {p2}? A ;");
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{(p1&&p1a)}?->:s2=>1\n" +
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p2}?->:s3=>2\n";
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void testOrPredicates() throws Exception {
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | {p2}? A ;\n" +
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p1}? A | {p1a}? A ;");
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s1-{(p1a||p1)}?->:s2=>1\n" +
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s1-{p2}?->:s3=>2\n";
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIgnoresHoistingDepthGreaterThanZero() throws Exception {
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : A {p1}? | A {p2}?;");
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->:s1=>1\n";
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, new int[] {2},
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  new int[] {1,2}, "A", null, null, 2, false);
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIgnoresPredsHiddenByActions() throws Exception {
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : {a1} {p1}? A | {a2} {p2}? A ;");
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->:s1=>1\n";
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, new int[] {2},
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  new int[] {1,2}, "A", null, null, 2, true);
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIgnoresPredsHiddenByActionsOneAlt() throws Exception {
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : {p1}? A | {a2} {p2}? A ;"); // ok since 1 pred visible
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p1}?->:s2=>1\n" +
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{true}?->:s3=>2\n";
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null,
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  null, null, null, null, 0, true);
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/*
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIncompleteSemanticHoistedContextk2() throws Exception {
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorQueue equeue = new ErrorQueue();
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorManager.setErrorListener(equeue);
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar t;\n"+
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | A B;\n" +
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p1}? A B | A B ;");
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-B->:s2=>1\n";
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, new int[] {2},
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  new int[] {1,2}, "A B", new int[] {1}, null, 3);
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testHoist2() throws Exception {
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | c ;\n" +
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p1}? A ;\n" +
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"c : {p2}? A ;\n");
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p1}?->:s2=>1\n" +
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p2}?->:s3=>2\n";
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testHoistCorrectContext() throws Exception {
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | {p2}? ID ;\n" +
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p1}? ID | INT ;\n");
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =  // only tests after ID, not INT :)
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-ID->.s1\n" +
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-INT->:s2=>1\n" +
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p1}?->:s2=>1\n" +
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p2}?->:s3=>2\n";
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testDefaultPredNakedAltIsLast() throws Exception {
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | ID ;\n" +
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p1}? ID | INT ;\n");
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-ID->.s1\n" +
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-INT->:s2=>1\n" +
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p1}?->:s2=>1\n" +
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{true}?->:s3=>2\n";
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testDefaultPredNakedAltNotLast() throws Exception {
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : ID | b ;\n" +
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p1}? ID | INT ;\n");
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-ID->.s1\n" +
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-INT->:s3=>2\n" +
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{!(p1)}?->:s2=>1\n" +
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p1}?->:s3=>2\n";
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testLeftRecursivePred() throws Exception {
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// No analysis possible. but probably good to fail.  Not sure we really want
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// left-recursion even if guarded with pred.
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"s : a ;\n" +
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : {p1}? a | ID ;\n");
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-ID->.s1\n" +
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p1}?->:s2=>1\n" +
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{true}?->:s3=>2\n";
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		DecisionProbe.verbose=true; // make sure we get all error info
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorQueue equeue = new ErrorQueue();
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorManager.setErrorListener(equeue);
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CodeGenerator generator = new CodeGenerator(newTool(), g, "Java");
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		g.setCodeGenerator(generator);
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( g.getNumberOfDecisions()==0 ) {
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			g.buildNFA();
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			g.createLookaheadDFAs(false);
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		DFA dfa = g.getLookaheadDFA(1);
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(null, dfa); // can't analyze.
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/*
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = serializer.serialize(dfa.startState);
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		*/
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("unexpected number of expected problems", 1, equeue.size());
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Message msg = (Message)equeue.errors.get(0);
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertTrue("warning must be a left recursion msg",
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				    msg instanceof LeftRecursionCyclesMessage);
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIgnorePredFromLL2AltLastAltIsDefaultTrue() throws Exception {
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : {p1}? A B | A C | {p2}? A | {p3}? A | A ;\n");
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// two situations of note:
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// 1. A B syntax is enough to predict that alt, so p1 is not used
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//    to distinguish it from alts 2..5
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// 2. Alts 3, 4, 5 are nondeterministic with upon A.  p2, p3 and the
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//    complement of p2||p3 is sufficient to resolve the conflict. Do
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//    not include alt 1's p1 pred in the "complement of other alts"
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//    because it is not considered nondeterministic with alts 3..5
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-B->:s2=>1\n" +
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-C->:s3=>2\n" +
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p2}?->:s4=>3\n" +
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p3}?->:s5=>4\n" +
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{true}?->:s6=>5\n";
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIgnorePredFromLL2AltPredUnionNeeded() throws Exception {
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : {p1}? A B | A C | {p2}? A | A | {p3}? A ;\n");
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// two situations of note:
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// 1. A B syntax is enough to predict that alt, so p1 is not used
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//    to distinguish it from alts 2..5
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// 2. Alts 3, 4, 5 are nondeterministic with upon A.  p2, p3 and the
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//    complement of p2||p3 is sufficient to resolve the conflict. Do
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//    not include alt 1's p1 pred in the "complement of other alts"
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//    because it is not considered nondeterministic with alts 3..5
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-B->:s2=>1\n" +
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-C->:s3=>2\n" +
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{!((p3||p2))}?->:s5=>4\n" +
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p2}?->:s4=>3\n" +
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p3}?->:s6=>5\n";
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testPredGets2SymbolSyntacticContext() throws Exception {
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | A B | C ;\n" +
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p1}? A B ;\n");
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-C->:s5=>3\n" +
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-B->.s2\n" +
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{p1}?->:s3=>1\n" +
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{true}?->:s4=>2\n";
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testMatchesLongestThenTestPred() throws Exception {
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | c ;\n" +
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p}? A ;\n" +
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"c : {q}? (A|B)+ ;");
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-B->:s3=>2\n" +
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p}?->:s2=>1\n" +
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{q}?->:s3=>2\n";
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testPredsUsedAfterRecursionOverflow() throws Exception {
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// analysis must bail out due to non-LL(*) nature (ovf)
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// retries with k=1 (but with LL(*) algorithm not optimized version
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// as it has preds)
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar P;\n"+
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"s : {p1}? e '.' | {p2}? e ':' ;\n" +
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"e : '(' e ')' | INT ;\n");
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'('->.s1\n" +
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-INT->.s4\n" +
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p1}?->:s2=>1\n" +
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p2}?->:s3=>2\n" +
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s4-{p1}?->:s2=>1\n" +
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s4-{p2}?->:s3=>2\n";
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		DecisionProbe.verbose=true; // make sure we get all error info
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorQueue equeue = new ErrorQueue();
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorManager.setErrorListener(equeue);
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CodeGenerator generator = new CodeGenerator(newTool(), g, "Java");
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		g.setCodeGenerator(generator);
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( g.getNumberOfDecisions()==0 ) {
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			g.buildNFA();
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			g.createLookaheadDFAs(false);
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("unexpected number of expected problems", 0, equeue.size());
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testPredsUsedAfterK2FailsNoRecursionOverflow() throws Exception {
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// analysis must bail out due to non-LL(*) nature (ovf)
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// retries with k=1 (but with LL(*) algorithm not optimized version
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// as it has preds)
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar P;\n" +
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {k=2;}\n"+
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"s : {p1}? e '.' | {p2}? e ':' ;\n" +
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"e : '(' e ')' | INT ;\n");
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'('->.s1\n" +
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-INT->.s6\n" +
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-'('->.s2\n" +
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-INT->.s5\n" +
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{p1}?->:s3=>1\n" +
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{p2}?->:s4=>2\n" +
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s5-{p1}?->:s3=>1\n" +
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s5-{p2}?->:s4=>2\n" +
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s6-'.'->:s3=>1\n" +
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s6-':'->:s4=>2\n";
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		DecisionProbe.verbose=true; // make sure we get all error info
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorQueue equeue = new ErrorQueue();
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorManager.setErrorListener(equeue);
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CodeGenerator generator = new CodeGenerator(newTool(), g, "Java");
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		g.setCodeGenerator(generator);
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( g.getNumberOfDecisions()==0 ) {
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			g.buildNFA();
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			g.createLookaheadDFAs(false);
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("unexpected number of expected problems", 0, equeue.size());
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testLexerMatchesLongestThenTestPred() throws Exception {
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar P;\n"+
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : {p}? 'a' ;\n" +
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : {q}? ('a'|'b')+ ;");
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'a'->.s1\n" +
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'b'->:s4=>2\n" +
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-'a'..'b'->:s4=>2\n" +
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-<EOT>->.s2\n" +
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{p}?->:s3=>1\n" +
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{q}?->:s4=>2\n";
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 2, expecting, null, null, null, null, null, 0, false);
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testLexerMatchesLongestMinusPred() throws Exception {
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar P;\n"+
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : 'a' ;\n" +
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : ('a'|'b')+ ;");
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'a'->.s1\n" +
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'b'->:s3=>2\n" +
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-'a'..'b'->:s3=>2\n" +
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-<EOT>->:s2=>1\n";
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 2, expecting, null, null, null, null, null, 0, false);
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void testGatedPred() throws Exception {
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// gated preds are present on all arcs in predictor
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar P;\n"+
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : {p}? => 'a' ;\n" +
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"C : {q}? => ('a'|'b')+ ;");
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'a'&&{(q||p)}?->.s1\n" +
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s0-'b'&&{q}?->:s4=>2\n" +
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s1-'a'..'b'&&{q}?->:s4=>2\n" +
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s1-<EOT>&&{(q||p)}?->.s2\n" +
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s2-{p}?->:s3=>1\n" +
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s2-{q}?->:s4=>2\n";
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 2, expecting, null, null, null, null, null, 0, false);
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testGatedPredHoistsAndCanBeInStopState() throws Exception {
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// I found a bug where merging stop states made us throw away
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// a stop state with a gated pred!
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar u;\n" +
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b+ ;\n" +
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : 'x' | {p}?=> 'y' ;");
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'x'->:s2=>1\n" +
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'y'&&{p}?->:s3=>1\n" +
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-EOF->:s1=>2\n";
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void testGatedPredInCyclicDFA() throws Exception {
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar P;\n"+
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : {p}?=> ('a')+ 'x' ;\n" +
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"B : {q}?=> ('a'|'b')+ 'x' ;");
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'a'&&{(q||p)}?->.s1\n" +
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s0-'b'&&{q}?->:s5=>2\n" +
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s1-'a'&&{(q||p)}?->.s1\n" +
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s1-'b'&&{q}?->:s5=>2\n" +
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s1-'x'&&{(q||p)}?->.s2\n" +
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s2-<EOT>&&{(q||p)}?->.s3\n" +
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s3-{p}?->:s4=>1\n" +
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s3-{q}?->:s5=>2\n";
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 3, expecting, null, null, null, null, null, 0, false);
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testGatedPredNotActuallyUsedOnEdges() throws Exception {
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar P;\n"+
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : ('a' | {p}?=> 'a')\n" +
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  | 'a' 'b'\n" +
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;");
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting1 =
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'a'->.s1\n" +
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{!(p)}?->:s2=>1\n" +  	// Used to disambig subrule
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p}?->:s3=>2\n";
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// rule A decision can't test p from s0->1 because 'a' is valid
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// for alt1 *and* alt2 w/o p.  Can't test p from s1 to s3 because
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// we might have passed the first alt of subrule.  The same state
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// is listed in s2 in 2 different configurations: one with and one
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// w/o p.  Can't test therefore.  p||true == true.
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting2 =
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'a'->.s1\n" +
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-'b'->:s2=>2\n" +
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-<EOT>->:s3=>1\n";
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting1, null, null, null, null, null, 0, false);
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 2, expecting2, null, null, null, null, null, 0, false);
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testGatedPredDoesNotForceAllToBeGated() throws Exception {
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar w;\n" +
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | c ;\n" +
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p}? B ;\n" +
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"c : {q}?=> d ;\n" +
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"d : {r}? C ;\n");
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-B->:s1=>1\n" +
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-C&&{q}?->:s2=>2\n";
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testGatedPredDoesNotForceAllToBeGated2() throws Exception {
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar w;\n" +
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | c ;\n" +
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p}? B ;\n" +
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"c : {q}?=> d ;\n" +
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"d : {r}?=> C\n" +
529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  | B\n" +
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n");
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-B->.s1\n" +
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-C&&{(q&&r)}?->:s3=>2\n" +
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p}?->:s2=>1\n" +
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{q}?->:s3=>2\n";
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testORGatedPred() throws Exception {
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar w;\n" +
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | c ;\n" +
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p}? B ;\n" +
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"c : {q}?=> d ;\n" +
545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"d : {r}?=> C\n" +
546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  | {s}?=> B\n" +
547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n");
548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-B->.s1\n" +
550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-C&&{(q&&r)}?->:s3=>2\n" +
551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{(q&&s)}?->:s3=>2\n" +
552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p}?->:s2=>1\n";
553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** The following grammar should yield an error that rule 'a' has
557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  insufficient semantic info pulled from 'b'.
558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIncompleteSemanticHoistedContext() throws Exception {
560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorQueue equeue = new ErrorQueue();
561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorManager.setErrorListener(equeue);
562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar t;\n"+
564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | B;\n" +
565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p1}? B | B ;");
566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-B->:s1=>1\n";
568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, new int[] {2},
569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  new int[] {1,2}, "B", new int[] {1}, null, 3, false);
570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIncompleteSemanticHoistedContextk2() throws Exception {
573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorQueue equeue = new ErrorQueue();
574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorManager.setErrorListener(equeue);
575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar t;\n"+
577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | A B;\n" +
578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p1}? A B | A B ;");
579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-B->:s2=>1\n";
582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, new int[] {2},
583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  new int[] {1,2}, "A B", new int[] {1}, null, 3, false);
584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIncompleteSemanticHoistedContextInFOLLOW() throws Exception {
587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorQueue equeue = new ErrorQueue();
588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorManager.setErrorListener(equeue);
589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar t;\n"+
591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {k=1;}\n" + // limit to k=1 because it's LL(2); force pred hoist
592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : A? ;\n" + // need FOLLOW
593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : X a {p1}? A | Y a A ;"); // only one A is covered
594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->:s1=>1\n"; // s0-EOF->s2 branch pruned during optimization
596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, new int[] {2},
597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  new int[] {1,2}, "A", new int[] {2}, null, 3, false);
598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIncompleteSemanticHoistedContextInFOLLOWk2() throws Exception {
601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorQueue equeue = new ErrorQueue();
602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorManager.setErrorListener(equeue);
603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar t;\n"+
605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : (A B)? ;\n" + // need FOLLOW
606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : X a {p1}? A B | Y a A B | Z a ;"); // only first alt is covered
607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-EOF->:s3=>2\n" +
610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-B->:s2=>1\n";
611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null,
612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  new int[] {1,2}, "A B", new int[] {2}, null, 2, false);
613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIncompleteSemanticHoistedContextInFOLLOWDueToHiddenPred() throws Exception {
616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorQueue equeue = new ErrorQueue();
617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorManager.setErrorListener(equeue);
618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar t;\n"+
620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : (A B)? ;\n" + // need FOLLOW
621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : X a {p1}? A B | Y a {a1} {p2}? A B | Z a ;"); // only first alt is covered
622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->.s1\n" +
624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-EOF->:s3=>2\n" +
625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-B->:s2=>1\n";
626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null,
627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  new int[] {1,2}, "A B", new int[] {2}, null, 2, true);
628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** The following grammar should yield an error that rule 'a' has
631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  insufficient semantic info pulled from 'b'.  This is the same
632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  as the previous case except that the D prevents the B path from
633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  "pinching" together into a single NFA state.
634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This test also demonstrates that just because B D could predict
636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  alt 1 in rule 'a', it is unnecessary to continue NFA->DFA
637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  conversion to include an edge for D.  Alt 1 is the only possible
638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  prediction because we resolve the ambiguity by choosing alt 1.
639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testIncompleteSemanticHoistedContext2() throws Exception {
641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorQueue equeue = new ErrorQueue();
642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorManager.setErrorListener(equeue);
643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar t;\n"+
645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : b | B;\n" +
646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {p1}? B | B D ;");
647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-B->:s1=>1\n";
649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, new int[] {2},
650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  new int[] {1,2}, "B", new int[] {1},
651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  null, 3, false);
652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testTooFewSemanticPredicates() throws Exception {
655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar t;\n"+
657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : {p1}? A | A | A ;");
658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-A->:s1=>1\n";
660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, new int[] {2,3},
661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  new int[] {1,2,3}, "A",
662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  null, null, 2, false);
663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testPredWithK1() throws Exception {
666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"\tlexer grammar TLexer;\n" +
668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A\n" +
669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {\n" +
670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  k=1;\n" +
671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}\n" +
672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  : {p1}? ('x')+ '.'\n" +
673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  | {p2}? ('x')+ '.'\n" +
674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n");
675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'x'->.s1\n" +
677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p1}?->:s2=>1\n" +
678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-{p2}?->:s3=>2\n";
679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] unreachableAlts = null;
680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] nonDetAlts = null;
681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String ambigInput = null;
682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] insufficientPredAlts = null;
683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] danglingAlts = null;
684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int numWarnings = 0;
685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 3, expecting, unreachableAlts,
686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  nonDetAlts, ambigInput, insufficientPredAlts,
687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  danglingAlts, numWarnings, false);
688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test public void testPredWithArbitraryLookahead() throws Exception {
691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"\tlexer grammar TLexer;\n" +
693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"A : {p1}? ('x')+ '.'\n" +
694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  | {p2}? ('x')+ '.'\n" +
695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n");
696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-'x'->.s1\n" +
698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-'.'->.s2\n" +
699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s1-'x'->.s1\n" +
700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{p1}?->:s3=>1\n" +
701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s2-{p2}?->:s4=>2\n";
702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] unreachableAlts = null;
703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] nonDetAlts = null;
704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String ambigInput = null;
705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] insufficientPredAlts = null;
706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] danglingAlts = null;
707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int numWarnings = 0;
708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 3, expecting, unreachableAlts,
709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  nonDetAlts, ambigInput, insufficientPredAlts,
710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  danglingAlts, numWarnings, false);
711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	@Test
714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** For a DFA state with lots of configurations that have the same
715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  predicate, don't just OR them all together as it's a waste to
716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  test a||a||b||a||a etc...  ANTLR makes a unique set and THEN
717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  OR's them together.
718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void testUniquePredicateOR() throws Exception {
720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar v;\n" +
722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"\n" +
723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : {a}? b\n" +
724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  | {b}? b\n" +
725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n" +
726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"\n" +
727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"b : {c}? (X)+ ;\n" +
728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"\n" +
729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"c : a\n" +
730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  | b\n" +
731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n");
732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-X->.s1\n" +
734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s1-{((a&&c)||(b&&c))}?->:s2=>1\n" +
735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s1-{c}?->:s3=>2\n";
736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] unreachableAlts = null;
737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] nonDetAlts = null;
738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String ambigInput = null;
739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] insufficientPredAlts = null;
740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] danglingAlts = null;
741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int numWarnings = 0;
742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 3, expecting, unreachableAlts,
743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  nonDetAlts, ambigInput, insufficientPredAlts,
744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  danglingAlts, numWarnings, false);
745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @Test
748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void testSemanticContextPreventsEarlyTerminationOfClosure() throws Exception {
749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar T;\n" +
751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : loop SEMI | ID SEMI\n" +
752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  ;\n" +
753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"loop\n" +
754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"    : {while}? ID\n" +
755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"    | {do}? ID\n" +
756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"    | {for}? ID\n" +
757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"    ;");
758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			".s0-ID->.s1\n" +
760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s1-SEMI->.s2\n" +
761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s2-{(for||do||while)}?->:s3=>1\n" +
762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ".s2-{true}?->:s4=>2\n";
763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, null, null, null, null, null, 0, false);
764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// S U P P O R T
767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void _template() throws Exception {
769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar g = new Grammar(
770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"parser grammar t;\n"+
771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"a : A | B;");
772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String expecting =
773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"\n";
774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] unreachableAlts = null;
775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] nonDetAlts = new int[] {1,2};
776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String ambigInput = "L ID R";
777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] insufficientPredAlts = new int[] {1};
778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int[] danglingAlts = null;
779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int numWarnings = 1;
780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkDecision(g, 1, expecting, unreachableAlts,
781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  nonDetAlts, ambigInput, insufficientPredAlts,
782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  danglingAlts, numWarnings, false);
783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected void checkDecision(Grammar g,
786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								 int decision,
787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								 String expecting,
788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								 int[] expectingUnreachableAlts,
789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								 int[] expectingNonDetAlts,
790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								 String expectingAmbigInput,
791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								 int[] expectingInsufficientPredAlts,
792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								 int[] expectingDanglingAlts,
793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								 int expectingNumWarnings,
794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								 boolean hasPredHiddenByAction)
795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		throws Exception
796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		DecisionProbe.verbose=true; // make sure we get all error info
798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorQueue equeue = new ErrorQueue();
799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ErrorManager.setErrorListener(equeue);
800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CodeGenerator generator = new CodeGenerator(newTool(), g, "Java");
801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		g.setCodeGenerator(generator);
802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// mimic actions of org.antlr.Tool first time for grammar g
803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( g.getNumberOfDecisions()==0 ) {
804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			g.buildNFA();
805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			g.createLookaheadDFAs(false);
806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( equeue.size()!=expectingNumWarnings ) {
809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			System.err.println("Warnings issued: "+equeue);
810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals("unexpected number of expected problems",
813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				   expectingNumWarnings, equeue.size());
814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		DFA dfa = g.getLookaheadDFA(decision);
816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		FASerializer serializer = new FASerializer(g);
817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String result = serializer.serialize(dfa.startState);
818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.print(result);
819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List unreachableAlts = dfa.getUnreachableAlts();
820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// make sure unreachable alts are as expected
822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( expectingUnreachableAlts!=null ) {
823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			BitSet s = new BitSet();
824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			s.addAll(expectingUnreachableAlts);
825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			BitSet s2 = new BitSet();
826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			s2.addAll(unreachableAlts);
827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertEquals("unreachable alts mismatch", s, s2);
828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else {
830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertEquals("unreachable alts mismatch", 0,
831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						 unreachableAlts!=null?unreachableAlts.size():0);
832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// check conflicting input
835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( expectingAmbigInput!=null ) {
836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// first, find nondet message
837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Message msg = getNonDeterminismMessage(equeue.warnings);
838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertNotNull("no nondeterminism warning?", msg);
839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertTrue("expecting nondeterminism; found "+msg.getClass().getName(),
840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			msg instanceof GrammarNonDeterminismMessage);
841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarNonDeterminismMessage nondetMsg =
842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				getNonDeterminismMessage(equeue.warnings);
843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			List labels =
844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				nondetMsg.probe.getSampleNonDeterministicInputSequence(nondetMsg.problemState);
845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String input = nondetMsg.probe.getInputSequenceDisplay(labels);
846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertEquals(expectingAmbigInput, input);
847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// check nondet alts
850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( expectingNonDetAlts!=null ) {
851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarNonDeterminismMessage nondetMsg =
852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				getNonDeterminismMessage(equeue.warnings);
853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertNotNull("found no nondet alts; expecting: "+
854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										str(expectingNonDetAlts), nondetMsg);
855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			List nonDetAlts =
856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				nondetMsg.probe.getNonDeterministicAltsForState(nondetMsg.problemState);
857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// compare nonDetAlts with expectingNonDetAlts
858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			BitSet s = new BitSet();
859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			s.addAll(expectingNonDetAlts);
860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			BitSet s2 = new BitSet();
861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			s2.addAll(nonDetAlts);
862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertEquals("nondet alts mismatch", s, s2);
863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertEquals("mismatch between expected hasPredHiddenByAction", hasPredHiddenByAction,
864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						 nondetMsg.problemState.dfa.hasPredicateBlockedByAction);
865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else {
867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// not expecting any nondet alts, make sure there are none
868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarNonDeterminismMessage nondetMsg =
869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				getNonDeterminismMessage(equeue.warnings);
870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertNull("found nondet alts, but expecting none", nondetMsg);
871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( expectingInsufficientPredAlts!=null ) {
874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarInsufficientPredicatesMessage insuffPredMsg =
875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				getGrammarInsufficientPredicatesMessage(equeue.warnings);
876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertNotNull("found no GrammarInsufficientPredicatesMessage alts; expecting: "+
877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										str(expectingNonDetAlts), insuffPredMsg);
878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Map<Integer, Set<Token>> locations = insuffPredMsg.altToLocations;
879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Set actualAlts = locations.keySet();
880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			BitSet s = new BitSet();
881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			s.addAll(expectingInsufficientPredAlts);
882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			BitSet s2 = new BitSet();
883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			s2.addAll(actualAlts);
884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertEquals("mismatch between insufficiently covered alts", s, s2);
885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertEquals("mismatch between expected hasPredHiddenByAction", hasPredHiddenByAction,
886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						 insuffPredMsg.problemState.dfa.hasPredicateBlockedByAction);
887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else {
889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// not expecting any nondet alts, make sure there are none
890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarInsufficientPredicatesMessage nondetMsg =
891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				getGrammarInsufficientPredicatesMessage(equeue.warnings);
892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( nondetMsg!=null ) {
893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				System.out.println(equeue.warnings);
894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			assertNull("found insufficiently covered alts, but expecting none", nondetMsg);
896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		assertEquals(expecting, result);
899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected GrammarNonDeterminismMessage getNonDeterminismMessage(List warnings) {
902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = 0; i < warnings.size(); i++) {
903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Message m = (Message) warnings.get(i);
904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( m instanceof GrammarNonDeterminismMessage ) {
905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return (GrammarNonDeterminismMessage)m;
906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return null;
909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected GrammarInsufficientPredicatesMessage getGrammarInsufficientPredicatesMessage(List warnings) {
912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = 0; i < warnings.size(); i++) {
913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Message m = (Message) warnings.get(i);
914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( m instanceof GrammarInsufficientPredicatesMessage ) {
915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return (GrammarInsufficientPredicatesMessage)m;
916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return null;
919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected String str(int[] elements) {
922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		StringBuffer buf = new StringBuffer();
923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = 0; i < elements.length; i++) {
924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( i>0 ) {
925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append(", ");
926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			int element = elements[i];
928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			buf.append(element);
929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return buf.toString();
931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
933