forked from jasder/antlr
Fix handling of alts with some configs predicated and some configs unpredicated (should be treated as always true)
This commit is contained in:
parent
9c554a002b
commit
46d5458617
|
@ -565,21 +565,28 @@ public class ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
int nalts = decState.getNumberOfTransitions();
|
||||
List<DFAState.PredPrediction> predPredictions =
|
||||
predicateDFAState(D, D.configset, outerContext, nalts);
|
||||
IntervalSet conflictingAlts = getConflictingAltsFromConfigSet(D.configset);
|
||||
if ( D.predicates.size() < conflictingAlts.size() ) {
|
||||
reportInsufficientPredicates(dfa, startIndex, input.index(),
|
||||
conflictingAlts,
|
||||
decState,
|
||||
getPredsForAmbigAlts(conflictingAlts, D.configset, nalts),
|
||||
D.configset,
|
||||
false);
|
||||
if ( predPredictions!=null ) {
|
||||
IntervalSet conflictingAlts = getConflictingAltsFromConfigSet(D.configset);
|
||||
if ( D.predicates.size() < conflictingAlts.size() ) {
|
||||
reportInsufficientPredicates(dfa, startIndex, input.index(),
|
||||
conflictingAlts,
|
||||
decState,
|
||||
getPredsForAmbigAlts(conflictingAlts, D.configset, nalts),
|
||||
D.configset,
|
||||
false);
|
||||
}
|
||||
input.seek(startIndex);
|
||||
predictedAlt = evalSemanticContext(predPredictions, outerContext);
|
||||
if ( predictedAlt!=ATN.INVALID_ALT_NUMBER ) {
|
||||
return predictedAlt;
|
||||
}
|
||||
|
||||
if (D.prediction == ATN.INVALID_ALT_NUMBER) {
|
||||
throw noViableAlt(input, outerContext, D.configset, startIndex);
|
||||
}
|
||||
|
||||
predictedAlt = D.prediction;
|
||||
}
|
||||
input.seek(startIndex);
|
||||
predictedAlt = evalSemanticContext(predPredictions, outerContext);
|
||||
if ( predictedAlt!=ATN.INVALID_ALT_NUMBER ) {
|
||||
return predictedAlt;
|
||||
}
|
||||
throw noViableAlt(input, outerContext, D.configset, startIndex);
|
||||
}
|
||||
|
||||
if ( D.isAcceptState ) return predictedAlt;
|
||||
|
@ -736,14 +743,9 @@ public class ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
// we have a validating predicate; test it
|
||||
// Update DFA so reach becomes accept state with predicate
|
||||
predPredictions = getPredicatePredictions(conflictingAlts, altToPred);
|
||||
if ( D.isCtxSensitive ) {
|
||||
// D.ctxToPredicates.put(outerContext, predPredictions);
|
||||
}
|
||||
else {
|
||||
D.predicates = predPredictions;
|
||||
}
|
||||
D.predicates = predPredictions;
|
||||
D.prediction = ATN.INVALID_ALT_NUMBER; // make sure we use preds
|
||||
}
|
||||
D.prediction = ATN.INVALID_ALT_NUMBER; // make sure we use preds
|
||||
return predPredictions;
|
||||
}
|
||||
|
||||
|
@ -754,11 +756,18 @@ public class ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
// REACH=[1|1|[]|0:0, 1|2|[]|0:1]
|
||||
SemanticContext[] altToPred = new SemanticContext[nalts +1];
|
||||
int n = altToPred.length;
|
||||
for (int i = 0; i < n; i++) altToPred[i] = SemanticContext.NONE;
|
||||
int nPredAlts = 0;
|
||||
for (ATNConfig c : configs) {
|
||||
if ( c.semanticContext!=SemanticContext.NONE && ambigAlts.contains(c.alt) ) {
|
||||
if ( ambigAlts.contains(c.alt) ) {
|
||||
altToPred[c.alt] = SemanticContext.or(altToPred[c.alt], c.semanticContext);
|
||||
}
|
||||
}
|
||||
|
||||
int nPredAlts = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (altToPred[i] == null) {
|
||||
altToPred[i] = SemanticContext.NONE;
|
||||
}
|
||||
else if (altToPred[i] != SemanticContext.NONE) {
|
||||
nPredAlts++;
|
||||
}
|
||||
}
|
||||
|
@ -817,10 +826,12 @@ public class ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
predictedAlt = pair.alt; // default prediction
|
||||
break;
|
||||
}
|
||||
|
||||
boolean evaluatedResult = pair.pred.eval(parser, outerContext);
|
||||
if ( debug || dfa_debug ) {
|
||||
System.out.println("eval pred "+pair+"="+pair.pred.eval(parser, outerContext));
|
||||
System.out.println("eval pred "+pair+"="+evaluatedResult);
|
||||
}
|
||||
if ( pair.pred.eval(parser, outerContext) ) {
|
||||
if ( evaluatedResult ) {
|
||||
if ( debug || dfa_debug ) System.out.println("PREDICT "+pair.alt);
|
||||
predictedAlt = pair.alt;
|
||||
break;
|
||||
|
|
|
@ -189,14 +189,15 @@ public abstract class SemanticContext {
|
|||
}
|
||||
|
||||
public static SemanticContext and(SemanticContext a, SemanticContext b) {
|
||||
if ( a == NONE ) return b;
|
||||
if ( b == NONE ) return a;
|
||||
if ( a == null || a == NONE ) return b;
|
||||
if ( b == null || b == NONE ) return a;
|
||||
return new AND(a, b);
|
||||
}
|
||||
|
||||
public static SemanticContext or(SemanticContext a, SemanticContext b) {
|
||||
if ( a == NONE ) return b;
|
||||
if ( b == NONE ) return a;
|
||||
if ( a == null ) return b;
|
||||
if ( b == null ) return a;
|
||||
if ( a == NONE || b == NONE ) return NONE;
|
||||
return new OR(a, b);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,7 +274,7 @@ public class TestSemPredEvalParser extends BaseTest {
|
|||
"alt 1\n";
|
||||
assertEquals(expecting, found);
|
||||
|
||||
expecting = "";
|
||||
expecting = null;
|
||||
assertEquals(expecting, stderrDuringParse);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue