forked from jasder/antlr
mirrored parser ATN sim changes in lexer ATN sim for thread safety. reduced contention for contextCache.
This commit is contained in:
parent
b0b30fec68
commit
754e6eb593
|
@ -706,12 +706,15 @@ public class LexerATNSimulator extends ATNSimulator {
|
|||
|
||||
protected void addDFAEdge(@NotNull DFAState p, int t, @NotNull DFAState q) {
|
||||
if (t < 0 || t > MAX_DFA_EDGE) return; // Only track edges within the DFA bounds
|
||||
DFA dfa = decisionToDFA[mode];
|
||||
synchronized (dfa) {
|
||||
if ( p.edges==null ) {
|
||||
// make room for tokens 1..n and -1 masquerading as index 0
|
||||
p.edges = new DFAState[MAX_DFA_EDGE+1]; // TODO: make adaptive
|
||||
}
|
||||
p.edges[t] = q; // connect
|
||||
}
|
||||
}
|
||||
|
||||
/** Add a new DFA state if there isn't one with this set of
|
||||
configurations already. This method also detects the first
|
||||
|
@ -724,11 +727,6 @@ public class LexerATNSimulator extends ATNSimulator {
|
|||
if ( configs.hasSemanticContext ) return null;
|
||||
|
||||
DFAState proposed = new DFAState(configs);
|
||||
DFAState existing = decisionToDFA[mode].states.get(proposed);
|
||||
if ( existing!=null ) return existing;
|
||||
|
||||
DFAState newState = proposed;
|
||||
|
||||
ATNConfig firstConfigWithRuleStopState = null;
|
||||
for (ATNConfig c : configs) {
|
||||
if ( c.state instanceof RuleStopState ) {
|
||||
|
@ -738,19 +736,27 @@ public class LexerATNSimulator extends ATNSimulator {
|
|||
}
|
||||
|
||||
if ( firstConfigWithRuleStopState!=null ) {
|
||||
newState.isAcceptState = true;
|
||||
newState.lexerRuleIndex = firstConfigWithRuleStopState.state.ruleIndex;
|
||||
newState.lexerActionIndex =
|
||||
proposed.isAcceptState = true;
|
||||
proposed.lexerRuleIndex = firstConfigWithRuleStopState.state.ruleIndex;
|
||||
proposed.lexerActionIndex =
|
||||
((LexerATNConfig)firstConfigWithRuleStopState).lexerActionIndex;
|
||||
newState.prediction = atn.ruleToTokenType[newState.lexerRuleIndex];
|
||||
proposed.prediction = atn.ruleToTokenType[proposed.lexerRuleIndex];
|
||||
}
|
||||
|
||||
newState.stateNumber = decisionToDFA[mode].states.size();
|
||||
DFA dfa = decisionToDFA[mode];
|
||||
synchronized (dfa) {
|
||||
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;
|
||||
decisionToDFA[mode].states.put(newState, newState);
|
||||
return newState;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DFA getDFA(int mode) {
|
||||
|
|
|
@ -283,9 +283,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
|||
if ( s.isCtxSensitive && !SLL ) {
|
||||
if ( dfa_debug ) System.out.println("ctx sensitive state "+outerContext+" in "+s);
|
||||
PredictionContext predictionCtx = PredictionContext.fromRuleContext(outerContext);
|
||||
synchronized (sharedContextCache) {
|
||||
predictionCtx = getCachedContext(predictionCtx);
|
||||
}
|
||||
Integer predI = s.contextToPredictedAlt.get(predictionCtx);
|
||||
if ( predI!=null ) {
|
||||
return predI; // ha! quick exit :)
|
||||
|
@ -543,9 +541,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
|||
greedy);
|
||||
// not accept state: isCtxSensitive
|
||||
PredictionContext predictionCtx = PredictionContext.fromRuleContext(outerContext);
|
||||
synchronized (sharedContextCache) {
|
||||
predictionCtx = getCachedContext(predictionCtx);
|
||||
}
|
||||
D.isCtxSensitive = true; // always force DFA to ATN simulate
|
||||
predictedAlt = fullCtxSet.uniqueAlt;
|
||||
D.prediction = ATN.INVALID_ALT_NUMBER;
|
||||
|
@ -1436,10 +1432,10 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
|||
if ( debug ) System.out.println("EDGE "+from+" -> "+to+" upon "+getTokenName(t));
|
||||
if ( from==null || t < -1 || to == null ) return;
|
||||
to = addDFAState(dfa, to); // used existing if possible not incoming
|
||||
synchronized (dfa) {
|
||||
if ( from.edges==null ) {
|
||||
from.edges = new DFAState[atn.maxTokenType+1+1]; // TODO: make adaptive
|
||||
}
|
||||
synchronized (dfa) {
|
||||
from.edges[t+1] = to; // connect
|
||||
}
|
||||
if ( debug ) System.out.println("DFA=\n"+dfa.toString(parser!=null?parser.getTokenNames():null));
|
||||
|
|
|
@ -416,11 +416,13 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
|||
return existing;
|
||||
}
|
||||
|
||||
synchronized (contextCache) {
|
||||
existing = contextCache.get(context);
|
||||
if (existing != null) {
|
||||
visited.put(context, existing);
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
PredictionContext[] parents = new PredictionContext[context.size()];
|
||||
|
@ -441,7 +443,9 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
|||
}
|
||||
|
||||
if (!changed) {
|
||||
synchronized (contextCache) {
|
||||
contextCache.add(context);
|
||||
}
|
||||
visited.put(context, context);
|
||||
return context;
|
||||
}
|
||||
|
@ -458,7 +462,9 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
|||
updated = new ArrayPredictionContext(parents, arrayPredictionContext.invokingStates);
|
||||
}
|
||||
|
||||
synchronized (contextCache) {
|
||||
contextCache.add(updated);
|
||||
}
|
||||
visited.put(updated, updated);
|
||||
visited.put(context, updated);
|
||||
|
||||
|
|
Loading…
Reference in New Issue