computeTargetState method
Compute a target state for an edge in the DFA, and attempt to add the computed state and corresponding edge to the DFA.
@param dfa The DFA @param previousD The current DFA state @param t The next input symbol
@return The computed target DFA state for the given input symbol
t
. If t
does not lead to a valid DFA state, this method
returns {@link #ERROR}.
Implementation
DFAState? computeTargetState(DFA dfa, DFAState previousD, int t) {
final reach = computeReachSet(previousD.configs, t, false);
if (reach == null) {
addDFAEdge(dfa, previousD, t, ATNSimulator.ERROR);
return ATNSimulator.ERROR;
}
// create new target state; we'll add to DFA after it's complete
DFAState? D = DFAState(configs: reach);
final predictedAlt = getUniqueAlt(reach);
if (debug) {
final altSubSets =
PredictionModeExtension.getConflictingAltSubsets(reach);
log('SLL altSubSets=$altSubSets'
', configs=$reach'
', predict=$predictedAlt, allSubsetsConflict=${PredictionModeExtension.allSubsetsConflict(altSubSets)}, conflictingAlts=${getConflictingAlts(reach)}');
}
if (predictedAlt != ATN.INVALID_ALT_NUMBER) {
// NO CONFLICT, UNIQUELY PREDICTED ALT
D.isAcceptState = true;
D.configs.uniqueAlt = predictedAlt;
D.prediction = predictedAlt;
} else if (PredictionModeExtension.hasSLLConflictTerminatingPrediction(
predictionMode, reach)) {
// MORE THAN ONE VIABLE ALTERNATIVE
D.configs.conflictingAlts = getConflictingAlts(reach);
D.requiresFullContext = true;
// in SLL-only mode, we will stop at this state and return the minimum alt
D.isAcceptState = true;
D.prediction = D.configs.conflictingAlts!.nextset(0);
}
if (D.isAcceptState && D.configs.hasSemanticContext) {
predicateDFAState(D, atn.getDecisionState(dfa.decision));
if (D.predicates != null) {
D.prediction = ATN.INVALID_ALT_NUMBER;
}
}
// all adds to dfa are done after we've created full D state
D = addDFAEdge(dfa, previousD, t, D);
return D;
}