protected virtual DFAState ComputeTargetState(DFA dfa, DFAState previousD, int t)
{
ATNConfigSet reach = ComputeReachSet(previousD.configSet, t, false);
if (reach == null)
{
AddDFAEdge(dfa, previousD, t, ERROR);
return ERROR;
}
// create new target state; we'll add to DFA after it's complete
DFAState D = new DFAState(reach);
int predictedAlt = GetUniqueAlt(reach);
if (debug)
{
ICollection<BitSet> altSubSets = PredictionMode.GetConflictingAltSubsets(reach.configs);
Console.WriteLine("SLL altSubSets=" + altSubSets +
", configs=" + reach +
", predict=" + predictedAlt + ", allSubsetsConflict=" +
PredictionMode.AllSubsetsConflict(altSubSets) + ", conflictingAlts=" +
GetConflictingAlts(reach));
}
if (predictedAlt != ATN.INVALID_ALT_NUMBER)
{
// NO CONFLICT, UNIQUELY PREDICTED ALT
D.isAcceptState = true;
D.configSet.uniqueAlt = predictedAlt;
D.prediction = predictedAlt;
}
else if (PredictionMode.HasSLLConflictTerminatingPrediction(mode, reach))
{
// MORE THAN ONE VIABLE ALTERNATIVE
D.configSet.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.configSet.conflictingAlts.NextSetBit(0);
}
if (D.isAcceptState && D.configSet.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;
}