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.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
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. */
|
/** This is all the parsing support code essentially; most of it is error recovery stuff. */
|
||||||
public abstract class Parser extends Recognizer<Token, ParserATNSimulator> {
|
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
|
* The error handling strategy for the parser. The default value is a new
|
||||||
* instance of {@link DefaultErrorStrategy}.
|
* instance of {@link DefaultErrorStrategy}.
|
||||||
|
@ -435,26 +446,30 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator> {
|
||||||
_input.getTokenSource().setTokenFactory(factory);
|
_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
|
* The ATN with bypass alternatives is expensive to create so we create it
|
||||||
* setters/getters. createATNWithBypassAlts() does the creation.
|
* lazily.
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException if the current parser does not
|
||||||
|
* implement the {@link #getSerializedATN()} method.
|
||||||
*/
|
*/
|
||||||
public void setATNWithBypassAlts(ATN atn) { }
|
@NotNull
|
||||||
public ATN getATNWithBypassAlts() { return null; }
|
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
|
synchronized (bypassAltsAtnCache) {
|
||||||
* part of the typical API--use compileParseTreePattern().
|
ATN result = bypassAltsAtnCache.get(serializedAtn);
|
||||||
*/
|
if (result == null) {
|
||||||
public void createATNWithBypassAlts() {
|
ATNDeserializationOptions deserializationOptions = new ATNDeserializationOptions();
|
||||||
if ( getATNWithBypassAlts()==null ) {
|
deserializationOptions.setGenerateRuleBypassTransitions(true);
|
||||||
synchronized (Parser.class) { // create just one pattern matcher
|
result = new ATNDeserializer(deserializationOptions).deserialize(serializedAtn.toCharArray());
|
||||||
if ( getATNWithBypassAlts()==null ) { // double-check
|
bypassAltsAtnCache.put(serializedAtn, result);
|
||||||
String sATN = getSerializedATN();
|
|
||||||
ATNDeserializationOptions deserializationOptions = new ATNDeserializationOptions();
|
|
||||||
deserializationOptions.setGenerateRuleBypassTransitions(true);
|
|
||||||
setATNWithBypassAlts( new ATNDeserializer(deserializationOptions).deserialize(sATN.toCharArray()) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +498,6 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator> {
|
||||||
public ParseTreePattern compileParseTreePattern(String pattern, int patternRuleIndex,
|
public ParseTreePattern compileParseTreePattern(String pattern, int patternRuleIndex,
|
||||||
Lexer lexer)
|
Lexer lexer)
|
||||||
{
|
{
|
||||||
createATNWithBypassAlts();
|
|
||||||
ParseTreePatternMatcher m = new ParseTreePatternMatcher(lexer, this);
|
ParseTreePatternMatcher m = new ParseTreePatternMatcher(lexer, this);
|
||||||
return m.compile(pattern, patternRuleIndex);
|
return m.compile(pattern, patternRuleIndex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,9 +132,6 @@ public class ParseTreePatternMatcher {
|
||||||
public ParseTreePatternMatcher(Lexer lexer, Parser parser) {
|
public ParseTreePatternMatcher(Lexer lexer, Parser parser) {
|
||||||
this.lexer = lexer;
|
this.lexer = lexer;
|
||||||
this.parser = parser;
|
this.parser = parser;
|
||||||
if ( parser!=null ) {
|
|
||||||
parser.createATNWithBypassAlts();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDelimiters(String start, String stop, String escapeLeft) {
|
public void setDelimiters(String start, String stop, String escapeLeft) {
|
||||||
|
|
|
@ -247,10 +247,6 @@ public class <parser.name> extends <superClass> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ATN getATN() { return _ATN; }
|
public ATN getATN() { return _ATN; }
|
||||||
@Override
|
|
||||||
public ATN getATNWithBypassAlts() { return _ATNWithBypassAlts; }
|
|
||||||
@Override
|
|
||||||
public void setATNWithBypassAlts(ATN atn) { _ATNWithBypassAlts = atn; }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map\<String, Integer> getTokenTypeMap() { return tokenNameToType; }
|
public Map\<String, Integer> getTokenTypeMap() { return tokenNameToType; }
|
||||||
|
@ -935,7 +931,6 @@ public static final String _serializedATN =
|
||||||
<endif>
|
<endif>
|
||||||
public static final ATN _ATN =
|
public static final ATN _ATN =
|
||||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||||
public static ATN _ATNWithBypassAlts;
|
|
||||||
static {
|
static {
|
||||||
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
||||||
for (int i = 0; i \< _ATN.getNumberOfDecisions(); i++) {
|
for (int i = 0; i \< _ATN.getNumberOfDecisions(); i++) {
|
||||||
|
|
Loading…
Reference in New Issue