use of org.antlr.v4.runtime.dfa.DFA in project antlr4 by antlr.
the class ParserATNSimulator method addDFAState.
/**
* Add state {@code D} to the DFA if it is not already present, and return
* the actual instance stored in the DFA. If a state equivalent to {@code D}
* is already in the DFA, the existing state is returned. Otherwise this
* method returns {@code D} after adding it to the DFA.
*
* <p>If {@code D} is {@link #ERROR}, this method returns {@link #ERROR} and
* does not change the DFA.</p>
*
* @param dfa The dfa
* @param D The DFA state to add
* @return The state stored in the DFA. This will be either the existing
* state if {@code D} is already in the DFA, or {@code D} itself if the
* state was not already present.
*/
protected DFAState addDFAState(DFA dfa, DFAState D) {
if (D == ERROR) {
return D;
}
synchronized (dfa.states) {
DFAState existing = dfa.states.get(D);
if (existing != null)
return existing;
D.stateNumber = dfa.states.size();
if (!D.configs.isReadonly()) {
D.configs.optimizeConfigs(this);
D.configs.setReadonly(true);
}
dfa.states.put(D, D);
if (debug)
System.out.println("adding new DFA state: " + D);
return D;
}
}
use of org.antlr.v4.runtime.dfa.DFA in project antlr4 by antlr.
the class LexerATNSimulator method execATN.
protected int execATN(CharStream input, DFAState ds0) {
// System.out.println("enter exec index "+input.index()+" from "+ds0.configs);
if (debug) {
System.out.format(Locale.getDefault(), "start state closure=%s\n", ds0.configs);
}
if (ds0.isAcceptState) {
// allow zero-length tokens
captureSimState(prevAccept, input, ds0);
}
int t = input.LA(1);
// s is current/from DFA state
DFAState s = ds0;
while (true) {
// while more work
if (debug) {
System.out.format(Locale.getDefault(), "execATN loop starting closure: %s\n", s.configs);
}
// As we move src->trg, src->trg, we keep track of the previous trg to
// avoid looking up the DFA state again, which is expensive.
// If the previous target was already part of the DFA, we might
// be able to avoid doing a reach operation upon t. If s!=null,
// it means that semantic predicates didn't prevent us from
// creating a DFA state. Once we know s!=null, we check to see if
// the DFA state has an edge already for t. If so, we can just reuse
// it's configuration set; there's no point in re-computing it.
// This is kind of like doing DFA simulation within the ATN
// simulation because DFA simulation is really just a way to avoid
// computing reach/closure sets. Technically, once we know that
// we have a previously added DFA state, we could jump over to
// the DFA simulator. But, that would mean popping back and forth
// a lot and making things more complicated algorithmically.
// This optimization makes a lot of sense for loops within DFA.
// A character will take us back to an existing DFA state
// that already has lots of edges out of it. e.g., .* in comments.
DFAState target = getExistingTargetState(s, t);
if (target == null) {
target = computeTargetState(input, s, t);
}
if (target == ERROR) {
break;
}
// end of the token.
if (t != IntStream.EOF) {
consume(input);
}
if (target.isAcceptState) {
captureSimState(prevAccept, input, target);
if (t == IntStream.EOF) {
break;
}
}
t = input.LA(1);
// flip; current DFA target becomes new src/from state
s = target;
}
return failOrAccept(prevAccept, input, s.configs, t);
}
use of org.antlr.v4.runtime.dfa.DFA 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.dfa.DFA 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.dfa.DFA in project antlr4 by antlr.
the class LexerATNSimulator method match.
public int match(CharStream input, int mode) {
this.mode = mode;
int mark = input.mark();
try {
this.startIndex = input.index();
this.prevAccept.reset();
DFA dfa = decisionToDFA[mode];
if (dfa.s0 == null) {
return matchATN(input);
} else {
return execATN(input, dfa.s0);
}
} finally {
input.release(mark);
}
}
Aggregations