Add boolean field ParserATNSimulator.reportAmbiguities (default true). When false, ambiguous alts aren't reported which allows usage of (the faster) incomplete semantic predicate evaluation even within execATN.

This commit is contained in:
Sam Harwell 2012-03-10 16:41:57 -06:00
parent 04cd48e88d
commit 50180825d9
1 changed files with 22 additions and 5 deletions

View File

@ -241,6 +241,17 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
@NotNull @NotNull
public final DFA[] decisionToDFA; public final DFA[] decisionToDFA;
/**
* When {@code true}, ambiguous alternatives are reported when they are
* encountered within {@link #execATN}. When {@code false}, these messages
* are suppressed. The default is {@code true}.
* <p>
* When messages about ambiguous alternatives are not required, setting this
* to {@code false} enables additional internal optimizations which may lose
* this information.
*/
public boolean reportAmbiguities = true;
/** Testing only! */ /** Testing only! */
public ParserATNSimulator(@NotNull ATN atn) { public ParserATNSimulator(@NotNull ATN atn) {
this(null, atn); this(null, atn);
@ -514,7 +525,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
!D.configset.dipsIntoOuterContext || !D.configset.dipsIntoOuterContext ||
k == 1 ) // SLL(1) == LL(1) k == 1 ) // SLL(1) == LL(1)
{ {
if ( !D.configset.hasSemanticContext ) { if ( reportAmbiguities && !D.configset.hasSemanticContext ) {
reportAmbiguity(dfa, D, startIndex, input.index(), D.configset.conflictingAlts, D.configset); reportAmbiguity(dfa, D, startIndex, input.index(), D.configset.conflictingAlts, D.configset);
} }
D.isAcceptState = true; D.isAcceptState = true;
@ -570,7 +581,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
if ( predPredictions!=null ) { if ( predPredictions!=null ) {
int stopIndex = input.index(); int stopIndex = input.index();
input.seek(startIndex); input.seek(startIndex);
IntervalSet alts = evalSemanticContext(predPredictions, outerContext, true); IntervalSet alts = evalSemanticContext(predPredictions, outerContext, reportAmbiguities);
D.prediction = ATN.INVALID_ALT_NUMBER; D.prediction = ATN.INVALID_ALT_NUMBER;
switch (alts.size()) { switch (alts.size()) {
case 0: case 0:
@ -582,7 +593,10 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
default: default:
// report ambiguity after predicate evaluation to make sure the correct // report ambiguity after predicate evaluation to make sure the correct
// set of ambig alts is reported. // set of ambig alts is reported.
reportAmbiguity(dfa, D, startIndex, stopIndex, alts, D.configset); if (reportAmbiguities) {
reportAmbiguity(dfa, D, startIndex, stopIndex, alts, D.configset);
}
return alts.getMinElement(); return alts.getMinElement();
} }
} }
@ -642,7 +656,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
// we have a validating predicate; test it // we have a validating predicate; test it
predPredictions = getPredicatePredictions(reach.conflictingAlts, altToPred); predPredictions = getPredicatePredictions(reach.conflictingAlts, altToPred);
input.seek(startIndex); input.seek(startIndex);
IntervalSet alts = evalSemanticContext(predPredictions, outerContext, true); IntervalSet alts = evalSemanticContext(predPredictions, outerContext, reportAmbiguities);
reach.uniqueAlt = ATN.INVALID_ALT_NUMBER; reach.uniqueAlt = ATN.INVALID_ALT_NUMBER;
switch (alts.size()) { switch (alts.size()) {
case 0: case 0:
@ -661,7 +675,10 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
} }
// must have conflict // must have conflict
reportAmbiguity(dfa, D, startIndex, input.index(), reach.conflictingAlts, reach); if (reportAmbiguities) {
reportAmbiguity(dfa, D, startIndex, input.index(), reach.conflictingAlts, reach);
}
reach.uniqueAlt = reach.conflictingAlts.getMinElement(); reach.uniqueAlt = reach.conflictingAlts.getMinElement();
return reach; return reach;