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