use of org.antlr.v4.runtime.atn.ATNConfigSet in project antlr4 by antlr.
the class LexerATNSimulator method addDFAEdge.
protected DFAState addDFAEdge(DFAState from, int t, ATNConfigSet q) {
/* leading to this call, ATNConfigSet.hasSemanticContext is used as a
* marker indicating dynamic predicate evaluation makes this edge
* dependent on the specific input sequence, so the static edge in the
* DFA should be omitted. The target DFAState is still created since
* execATN has the ability to resynchronize with the DFA state cache
* following the predicate evaluation step.
*
* TJP notes: next time through the DFA, we see a pred again and eval.
* If that gets us to a previously created (but dangling) DFA
* state, we can continue in pure DFA mode from there.
*/
boolean suppressEdge = q.hasSemanticContext;
q.hasSemanticContext = false;
DFAState to = addDFAState(q);
if (suppressEdge) {
return to;
}
addDFAEdge(from, t, to);
return to;
}
use of org.antlr.v4.runtime.atn.ATNConfigSet in project antlr4 by antlr.
the class LexerATNSimulator method addDFAState.
/** Add a new DFA state if there isn't one with this set of
configurations already. This method also detects the first
configuration containing an ATN rule stop state. Later, when
traversing the DFA, we will know which rule to accept.
*/
protected DFAState addDFAState(ATNConfigSet configs) {
/* the lexer evaluates predicates on-the-fly; by this point configs
* should not contain any configurations with unevaluated predicates.
*/
assert !configs.hasSemanticContext;
DFAState proposed = new DFAState(configs);
ATNConfig firstConfigWithRuleStopState = null;
for (ATNConfig c : configs) {
if (c.state instanceof RuleStopState) {
firstConfigWithRuleStopState = c;
break;
}
}
if (firstConfigWithRuleStopState != null) {
proposed.isAcceptState = true;
proposed.lexerActionExecutor = ((LexerATNConfig) firstConfigWithRuleStopState).getLexerActionExecutor();
proposed.prediction = atn.ruleToTokenType[firstConfigWithRuleStopState.state.ruleIndex];
}
DFA dfa = decisionToDFA[mode];
synchronized (dfa.states) {
DFAState existing = dfa.states.get(proposed);
if (existing != null)
return existing;
DFAState newState = proposed;
newState.stateNumber = dfa.states.size();
configs.setReadonly(true);
newState.configs = configs;
dfa.states.put(newState, newState);
return newState;
}
}
use of org.antlr.v4.runtime.atn.ATNConfigSet in project antlr4 by antlr.
the class LexerATNSimulator method matchATN.
protected int matchATN(CharStream input) {
ATNState startState = atn.modeToStartState.get(mode);
if (debug) {
System.out.format(Locale.getDefault(), "matchATN mode %d start: %s\n", mode, startState);
}
int old_mode = mode;
ATNConfigSet s0_closure = computeStartState(input, startState);
boolean suppressEdge = s0_closure.hasSemanticContext;
s0_closure.hasSemanticContext = false;
DFAState next = addDFAState(s0_closure);
if (!suppressEdge) {
decisionToDFA[mode].s0 = next;
}
int predict = execATN(input, next);
if (debug) {
System.out.format(Locale.getDefault(), "DFA after matchATN: %s\n", decisionToDFA[old_mode].toLexerString());
}
return predict;
}
use of org.antlr.v4.runtime.atn.ATNConfigSet in project antlr4 by antlr.
the class ParserATNSimulator method execATN.
/** Performs ATN simulation to compute a predicted alternative based
* upon the remaining input, but also updates the DFA cache to avoid
* having to traverse the ATN again for the same input sequence.
There are some key conditions we're looking for after computing a new
set of ATN configs (proposed DFA state):
* if the set is empty, there is no viable alternative for current symbol
* does the state uniquely predict an alternative?
* does the state have a conflict that would prevent us from
putting it on the work list?
We also have some key operations to do:
* add an edge from previous DFA state to potentially new DFA state, D,
upon current symbol but only if adding to work list, which means in all
cases except no viable alternative (and possibly non-greedy decisions?)
* collecting predicates and adding semantic context to DFA accept states
* adding rule context to context-sensitive DFA accept states
* consuming an input symbol
* reporting a conflict
* reporting an ambiguity
* reporting a context sensitivity
* reporting insufficient predicates
cover these cases:
dead end
single alt
single alt + preds
conflict
conflict + preds
*/
protected int execATN(DFA dfa, DFAState s0, TokenStream input, int startIndex, ParserRuleContext outerContext) {
if (debug || debug_list_atn_decisions) {
System.out.println("execATN decision " + dfa.decision + " exec LA(1)==" + getLookaheadName(input) + " line " + input.LT(1).getLine() + ":" + input.LT(1).getCharPositionInLine());
}
DFAState previousD = s0;
if (debug)
System.out.println("s0 = " + s0);
int t = input.LA(1);
while (true) {
// while more work
DFAState D = getExistingTargetState(previousD, t);
if (D == null) {
D = computeTargetState(dfa, previousD, t);
}
if (D == ERROR) {
// if any configs in previous dipped into outer context, that
// means that input up to t actually finished entry rule
// at least for SLL 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, previousD.configs, startIndex);
input.seek(startIndex);
int alt = getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previousD.configs, outerContext);
if (alt != ATN.INVALID_ALT_NUMBER) {
return alt;
}
throw e;
}
if (D.requiresFullContext && mode != PredictionMode.SLL) {
// IF PREDS, MIGHT RESOLVE TO SINGLE ALT => SLL (or syntax error)
BitSet conflictingAlts = D.configs.conflictingAlts;
if (D.predicates != null) {
if (debug)
System.out.println("DFA state has preds in DFA sim LL failover");
int conflictIndex = input.index();
if (conflictIndex != startIndex) {
input.seek(startIndex);
}
conflictingAlts = evalSemanticContext(D.predicates, outerContext, true);
if (conflictingAlts.cardinality() == 1) {
if (debug)
System.out.println("Full LL avoided");
return conflictingAlts.nextSetBit(0);
}
if (conflictIndex != startIndex) {
// restore the index so reporting the fallback to full
// context occurs with the index at the correct spot
input.seek(conflictIndex);
}
}
if (dfa_debug)
System.out.println("ctx sensitive state " + outerContext + " in " + D);
boolean fullCtx = true;
ATNConfigSet s0_closure = computeStartState(dfa.atnStartState, outerContext, fullCtx);
reportAttemptingFullContext(dfa, conflictingAlts, D.configs, startIndex, input.index());
int alt = execATNWithFullContext(dfa, D, s0_closure, input, startIndex, outerContext);
return alt;
}
if (D.isAcceptState) {
if (D.predicates == null) {
return D.prediction;
}
int stopIndex = input.index();
input.seek(startIndex);
BitSet alts = evalSemanticContext(D.predicates, outerContext, true);
switch(alts.cardinality()) {
case 0:
throw noViableAlt(input, outerContext, D.configs, startIndex);
case 1:
return alts.nextSetBit(0);
default:
// report ambiguity after predicate evaluation to make sure the correct
// set of ambig alts is reported.
reportAmbiguity(dfa, D, startIndex, stopIndex, false, alts, D.configs);
return alts.nextSetBit(0);
}
}
previousD = D;
if (t != IntStream.EOF) {
input.consume();
t = input.LA(1);
}
}
}
use of org.antlr.v4.runtime.atn.ATNConfigSet in project antlr4 by antlr.
the class ParserATNSimulator method reportAmbiguity.
/** If context sensitive parsing, we know it's ambiguity not conflict */
protected void reportAmbiguity(DFA dfa, // the DFA state from execATN() that had SLL conflicts
DFAState D, int startIndex, int stopIndex, boolean exact, BitSet ambigAlts, // configs that LL not SLL considered conflicting
ATNConfigSet configs) {
if (debug || retry_debug) {
Interval interval = Interval.of(startIndex, stopIndex);
System.out.println("reportAmbiguity " + ambigAlts + ":" + configs + ", input=" + parser.getTokenStream().getText(interval));
}
if (parser != null)
parser.getErrorListenerDispatch().reportAmbiguity(parser, dfa, startIndex, stopIndex, exact, ambigAlts, configs);
}
Aggregations