Clean up the caching of ATN instances with bypass alternatives
This commit is contained in:
parent
2618aa335a
commit
df61690758
|
@ -51,6 +51,8 @@ import org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/** This is all the parsing support code essentially; most of it is error recovery stuff. */
|
||||
public abstract class Parser extends Recognizer<Token, ParserATNSimulator> {
|
||||
|
@ -98,6 +100,15 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This field maps from the serialized ATN string to the deserialized {@link ATN} with
|
||||
* bypass alternatives.
|
||||
*
|
||||
* @see ATNDeserializationOptions#isGenerateRuleBypassTransitions()
|
||||
*/
|
||||
private static final Map<String, ATN> bypassAltsAtnCache =
|
||||
new WeakHashMap<String, ATN>();
|
||||
|
||||
/**
|
||||
* The error handling strategy for the parser. The default value is a new
|
||||
* instance of {@link DefaultErrorStrategy}.
|
||||
|
@ -435,26 +446,30 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator> {
|
|||
_input.getTokenSource().setTokenFactory(factory);
|
||||
}
|
||||
|
||||
/** The ATN with bypass alternatives is expensive to create so we create it lazily.
|
||||
* The actual generated parsers override this method. These are just
|
||||
* setters/getters. createATNWithBypassAlts() does the creation.
|
||||
/**
|
||||
* The ATN with bypass alternatives is expensive to create so we create it
|
||||
* lazily.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the current parser does not
|
||||
* implement the {@link #getSerializedATN()} method.
|
||||
*/
|
||||
public void setATNWithBypassAlts(ATN atn) { }
|
||||
public ATN getATNWithBypassAlts() { return null; }
|
||||
@NotNull
|
||||
public ATN getATNWithBypassAlts() {
|
||||
String serializedAtn = getSerializedATN();
|
||||
if (serializedAtn == null) {
|
||||
throw new UnsupportedOperationException("The current parser does not support an ATN with bypass alternatives.");
|
||||
}
|
||||
|
||||
/** Create and cache the ATN with bypass alternatives. This is not
|
||||
* part of the typical API--use compileParseTreePattern().
|
||||
*/
|
||||
public void createATNWithBypassAlts() {
|
||||
if ( getATNWithBypassAlts()==null ) {
|
||||
synchronized (Parser.class) { // create just one pattern matcher
|
||||
if ( getATNWithBypassAlts()==null ) { // double-check
|
||||
String sATN = getSerializedATN();
|
||||
synchronized (bypassAltsAtnCache) {
|
||||
ATN result = bypassAltsAtnCache.get(serializedAtn);
|
||||
if (result == null) {
|
||||
ATNDeserializationOptions deserializationOptions = new ATNDeserializationOptions();
|
||||
deserializationOptions.setGenerateRuleBypassTransitions(true);
|
||||
setATNWithBypassAlts( new ATNDeserializer(deserializationOptions).deserialize(sATN.toCharArray()) );
|
||||
}
|
||||
result = new ATNDeserializer(deserializationOptions).deserialize(serializedAtn.toCharArray());
|
||||
bypassAltsAtnCache.put(serializedAtn, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,7 +498,6 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator> {
|
|||
public ParseTreePattern compileParseTreePattern(String pattern, int patternRuleIndex,
|
||||
Lexer lexer)
|
||||
{
|
||||
createATNWithBypassAlts();
|
||||
ParseTreePatternMatcher m = new ParseTreePatternMatcher(lexer, this);
|
||||
return m.compile(pattern, patternRuleIndex);
|
||||
}
|
||||
|
|
|
@ -132,9 +132,6 @@ public class ParseTreePatternMatcher {
|
|||
public ParseTreePatternMatcher(Lexer lexer, Parser parser) {
|
||||
this.lexer = lexer;
|
||||
this.parser = parser;
|
||||
if ( parser!=null ) {
|
||||
parser.createATNWithBypassAlts();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDelimiters(String start, String stop, String escapeLeft) {
|
||||
|
|
|
@ -247,10 +247,6 @@ public class <parser.name> extends <superClass> {
|
|||
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
@Override
|
||||
public ATN getATNWithBypassAlts() { return _ATNWithBypassAlts; }
|
||||
@Override
|
||||
public void setATNWithBypassAlts(ATN atn) { _ATNWithBypassAlts = atn; }
|
||||
|
||||
@Override
|
||||
public Map\<String, Integer> getTokenTypeMap() { return tokenNameToType; }
|
||||
|
@ -935,7 +931,6 @@ public static final String _serializedATN =
|
|||
<endif>
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
public static ATN _ATNWithBypassAlts;
|
||||
static {
|
||||
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
||||
for (int i = 0; i \< _ATN.getNumberOfDecisions(); i++) {
|
||||
|
|
Loading…
Reference in New Issue