Semantic predicates now evaluate with standard min-alt selection

This commit is contained in:
Sam Harwell 2012-03-08 13:53:45 -06:00
parent a9e74ce399
commit 7525bb6e1d
2 changed files with 9 additions and 8 deletions

View File

@ -798,6 +798,8 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
public List<DFAState.PredPrediction> getPredicatePredictions(IntervalSet ambigAlts, SemanticContext[] altToPred) { public List<DFAState.PredPrediction> getPredicatePredictions(IntervalSet ambigAlts, SemanticContext[] altToPred) {
List<DFAState.PredPrediction> pairs = new ArrayList<DFAState.PredPrediction>(); List<DFAState.PredPrediction> pairs = new ArrayList<DFAState.PredPrediction>();
int firstUnpredicated = ATN.INVALID_ALT_NUMBER; int firstUnpredicated = ATN.INVALID_ALT_NUMBER;
// keep track of the position in pairs where the unpredicated choice should go
int firstUnpredicatedIndex = -1;
for (int i = 1; i < altToPred.length; i++) { for (int i = 1; i < altToPred.length; i++) {
SemanticContext pred = altToPred[i]; SemanticContext pred = altToPred[i];
// find first unpredicated but ambig alternative, if any. // find first unpredicated but ambig alternative, if any.
@ -809,6 +811,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
pred==SemanticContext.NONE && firstUnpredicated==ATN.INVALID_ALT_NUMBER ) pred==SemanticContext.NONE && firstUnpredicated==ATN.INVALID_ALT_NUMBER )
{ {
firstUnpredicated = i; firstUnpredicated = i;
firstUnpredicatedIndex = pairs.size();
} }
if ( pred!=null && pred!=SemanticContext.NONE ) { if ( pred!=null && pred!=SemanticContext.NONE ) {
pairs.add(new DFAState.PredPrediction(pred, i)); pairs.add(new DFAState.PredPrediction(pred, i));
@ -817,7 +820,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
if ( pairs.isEmpty() ) pairs = null; if ( pairs.isEmpty() ) pairs = null;
else if ( firstUnpredicated!=ATN.INVALID_ALT_NUMBER ) { else if ( firstUnpredicated!=ATN.INVALID_ALT_NUMBER ) {
// add default prediction if we found null predicate // add default prediction if we found null predicate
pairs.add(new DFAState.PredPrediction(null, firstUnpredicated)); pairs.add(firstUnpredicatedIndex, new DFAState.PredPrediction(null, firstUnpredicated));
} }
// System.out.println(Arrays.toString(altToPred)+"->"+pairs); // System.out.println(Arrays.toString(altToPred)+"->"+pairs);
return pairs; return pairs;

View File

@ -105,11 +105,9 @@ public class TestSemPredEvalParser extends BaseTest {
} }
@Test public void testOrder() throws Exception { @Test public void testOrder() throws Exception {
// Predicates disambiguate and so we don't arbitrarily choose the first alt // Under new predicate ordering rules (see antlr/antlr4#29), the first
// Here, there are n-1 predicates for n=2 alts and so we simulate // alt with an acceptable config (unpredicated, or predicated and evaluates
// the nth predicate as !(others). We do that by testing the // to true) is chosen.
// predicates first and then try the on predicated alternatives.
// Since the 2nd alternative has a true predicate, we always choose that one
String grammar = String grammar =
"grammar T;\n" + "grammar T;\n" +
"s : a {} a;\n" + // do 2x: once in ATN, next in DFA; "s : a {} a;\n" + // do 2x: once in ATN, next in DFA;
@ -125,8 +123,8 @@ public class TestSemPredEvalParser extends BaseTest {
String found = execParser("T.g", grammar, "TParser", "TLexer", "s", String found = execParser("T.g", grammar, "TParser", "TLexer", "s",
"x y", false); "x y", false);
String expecting = String expecting =
"alt 2\n" + "alt 1\n" +
"alt 2\n"; "alt 1\n";
assertEquals(expecting, found); assertEquals(expecting, found);
} }