use of org.antlr.v4.runtime.dfa.DFAState in project antlr4 by antlr.
the class DOTGenerator method getStateLabel.
protected String getStateLabel(DFAState s) {
if (s == null)
return "null";
StringBuilder buf = new StringBuilder(250);
buf.append('s');
buf.append(s.stateNumber);
if (s.isAcceptState) {
buf.append("=>").append(s.prediction);
}
if (s.requiresFullContext) {
buf.append("^");
}
if (grammar != null) {
Set<Integer> alts = s.getAltSet();
if (alts != null) {
buf.append("\\n");
// separate alts
IntegerList altList = new IntegerList();
altList.addAll(alts);
altList.sort();
Set<ATNConfig> configurations = s.configs;
for (int altIndex = 0; altIndex < altList.size(); altIndex++) {
int alt = altList.get(altIndex);
if (altIndex > 0) {
buf.append("\\n");
}
buf.append("alt");
buf.append(alt);
buf.append(':');
// get a list of configs for just this alt
// it will help us print better later
List<ATNConfig> configsInAlt = new ArrayList<ATNConfig>();
for (ATNConfig c : configurations) {
if (c.alt != alt)
continue;
configsInAlt.add(c);
}
int n = 0;
for (int cIndex = 0; cIndex < configsInAlt.size(); cIndex++) {
ATNConfig c = configsInAlt.get(cIndex);
n++;
buf.append(c.toString(null, false));
if ((cIndex + 1) < configsInAlt.size()) {
buf.append(", ");
}
if (n % 5 == 0 && (configsInAlt.size() - cIndex) > 3) {
buf.append("\\n");
}
}
}
}
}
String stateLabel = buf.toString();
return stateLabel;
}
use of org.antlr.v4.runtime.dfa.DFAState in project antlr4 by antlr.
the class ParserATNSimulator method computeTargetState.
/**
* 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
* {@code t}. If {@code t} does not lead to a valid DFA state, this method
* returns {@link #ERROR}.
*/
protected DFAState computeTargetState(DFA dfa, DFAState previousD, int t) {
ATNConfigSet reach = computeReachSet(previousD.configs, 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) {
Collection<BitSet> altSubSets = PredictionMode.getConflictingAltSubsets(reach);
System.out.println("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.configs.uniqueAlt = predictedAlt;
D.prediction = predictedAlt;
} else if (PredictionMode.hasSLLConflictTerminatingPrediction(mode, 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.nextSetBit(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;
}
use of org.antlr.v4.runtime.dfa.DFAState in project antlr4 by antlr.
the class ParserATNSimulator method execATNWithFullContext.
// comes back with reach.uniqueAlt set to a valid alt
protected int execATNWithFullContext(DFA dfa, // how far we got in SLL DFA before failing over
DFAState D, ATNConfigSet s0, TokenStream input, int startIndex, ParserRuleContext outerContext) {
if (debug || debug_list_atn_decisions) {
System.out.println("execATNWithFullContext " + s0);
}
boolean fullCtx = true;
boolean foundExactAmbig = false;
ATNConfigSet reach = null;
ATNConfigSet previous = s0;
input.seek(startIndex);
int t = input.LA(1);
int predictedAlt;
while (true) {
// while more work
// System.out.println("LL REACH "+getLookaheadName(input)+
// " from configs.size="+previous.size()+
// " line "+input.LT(1).getLine()+":"+input.LT(1).getCharPositionInLine());
reach = computeReachSet(previous, t, fullCtx);
if (reach == null) {
// if any configs in previous dipped into outer context, that
// means that input up to t actually finished entry rule
// at least for LL decision. Full LL doesn't dip into outer
// so don't need special case.
// We will get an error no matter what so delay until after
// decision; better error message. Also, no reachable target
// ATN states in SLL implies LL will also get nowhere.
// If conflict in states that dip out, choose min since we
// will get error no matter what.
NoViableAltException e = noViableAlt(input, outerContext, previous, startIndex);
input.seek(startIndex);
int alt = getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previous, outerContext);
if (alt != ATN.INVALID_ALT_NUMBER) {
return alt;
}
throw e;
}
Collection<BitSet> altSubSets = PredictionMode.getConflictingAltSubsets(reach);
if (debug) {
System.out.println("LL altSubSets=" + altSubSets + ", predict=" + PredictionMode.getUniqueAlt(altSubSets) + ", resolvesToJustOneViableAlt=" + PredictionMode.resolvesToJustOneViableAlt(altSubSets));
}
// System.out.println("altSubSets: "+altSubSets);
// System.err.println("reach="+reach+", "+reach.conflictingAlts);
reach.uniqueAlt = getUniqueAlt(reach);
// unique prediction?
if (reach.uniqueAlt != ATN.INVALID_ALT_NUMBER) {
predictedAlt = reach.uniqueAlt;
break;
}
if (mode != PredictionMode.LL_EXACT_AMBIG_DETECTION) {
predictedAlt = PredictionMode.resolvesToJustOneViableAlt(altSubSets);
if (predictedAlt != ATN.INVALID_ALT_NUMBER) {
break;
}
} else {
// Just keeps scarfing until we know what the conflict is
if (PredictionMode.allSubsetsConflict(altSubSets) && PredictionMode.allSubsetsEqual(altSubSets)) {
foundExactAmbig = true;
predictedAlt = PredictionMode.getSingleViableAlt(altSubSets);
break;
}
// else there are multiple non-conflicting subsets or
// we're not sure what the ambiguity is yet.
// So, keep going.
}
previous = reach;
if (t != IntStream.EOF) {
input.consume();
t = input.LA(1);
}
}
// not SLL.
if (reach.uniqueAlt != ATN.INVALID_ALT_NUMBER) {
reportContextSensitivity(dfa, predictedAlt, reach, startIndex, input.index());
return predictedAlt;
}
// We do not check predicates here because we have checked them
// on-the-fly when doing full context prediction.
/*
In non-exact ambiguity detection mode, we might actually be able to
detect an exact ambiguity, but I'm not going to spend the cycles
needed to check. We only emit ambiguity warnings in exact ambiguity
mode.
For example, we might know that we have conflicting configurations.
But, that does not mean that there is no way forward without a
conflict. It's possible to have nonconflicting alt subsets as in:
LL altSubSets=[{1, 2}, {1, 2}, {1}, {1, 2}]
from
[(17,1,[5 $]), (13,1,[5 10 $]), (21,1,[5 10 $]), (11,1,[$]),
(13,2,[5 10 $]), (21,2,[5 10 $]), (11,2,[$])]
In this case, (17,1,[5 $]) indicates there is some next sequence that
would resolve this without conflict to alternative 1. Any other viable
next sequence, however, is associated with a conflict. We stop
looking for input because no amount of further lookahead will alter
the fact that we should predict alternative 1. We just can't say for
sure that there is an ambiguity without looking further.
*/
reportAmbiguity(dfa, D, startIndex, input.index(), foundExactAmbig, reach.getAlts(), reach);
return predictedAlt;
}
use of org.antlr.v4.runtime.dfa.DFAState in project antlr4 by antlr.
the class ProfilingATNSimulator method getExistingTargetState.
@Override
protected DFAState getExistingTargetState(DFAState previousD, int t) {
// this method is called after each time the input position advances
// during SLL prediction
_sllStopIndex = _input.index();
DFAState existingTargetState = super.getExistingTargetState(previousD, t);
if (existingTargetState != null) {
// count only if we transition over a DFA state
decisions[currentDecision].SLL_DFATransitions++;
if (existingTargetState == ERROR) {
decisions[currentDecision].errors.add(new ErrorInfo(currentDecision, previousD.configs, _input, _startIndex, _sllStopIndex, false));
}
}
currentState = existingTargetState;
return existingTargetState;
}
use of org.antlr.v4.runtime.dfa.DFAState in project antlr4 by antlr.
the class DOTGenerator method getDOT.
public String getDOT(DFA dfa, boolean isLexer) {
if (dfa.s0 == null)
return null;
ST dot = stlib.getInstanceOf("dfa");
dot.add("name", "DFA" + dfa.decision);
dot.add("startState", dfa.s0.stateNumber);
// dot.add("useBox", Tool.internalOption_ShowATNConfigsInDFA);
dot.add("rankdir", rankdir);
// define stop states first; seems to be a bug in DOT where doublecircle
for (DFAState d : dfa.states.keySet()) {
if (!d.isAcceptState)
continue;
ST st = stlib.getInstanceOf("stopstate");
st.add("name", "s" + d.stateNumber);
st.add("label", getStateLabel(d));
dot.add("states", st);
}
for (DFAState d : dfa.states.keySet()) {
if (d.isAcceptState)
continue;
if (d.stateNumber == Integer.MAX_VALUE)
continue;
ST st = stlib.getInstanceOf("state");
st.add("name", "s" + d.stateNumber);
st.add("label", getStateLabel(d));
dot.add("states", st);
}
for (DFAState d : dfa.states.keySet()) {
if (d.edges != null) {
for (int i = 0; i < d.edges.length; i++) {
DFAState target = d.edges[i];
if (target == null)
continue;
if (target.stateNumber == Integer.MAX_VALUE)
continue;
// we shift up for EOF as -1 for parser
int ttype = i - 1;
String label = String.valueOf(ttype);
if (isLexer)
label = "'" + getEdgeLabel(new StringBuilder().appendCodePoint(i).toString()) + "'";
else if (grammar != null)
label = grammar.getTokenDisplayName(ttype);
ST st = stlib.getInstanceOf("edge");
st.add("label", label);
st.add("src", "s" + d.stateNumber);
st.add("target", "s" + target.stateNumber);
st.add("arrowhead", arrowhead);
dot.add("edges", st);
}
}
}
String output = dot.render();
return Utils.sortLinesInString(output);
}
Aggregations