Clean up the result caching for getTokenTypeMap and getRuleIndexMap

This commit is contained in:
Sam Harwell 2013-12-10 20:17:53 -06:00
parent df61690758
commit 75b8174dc8
2 changed files with 40 additions and 18 deletions

View File

@ -34,14 +34,22 @@ import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNSimulator;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.misc.Nullable;
import org.antlr.v4.runtime.misc.Utils;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
public abstract class Recognizer<Symbol, ATNInterpreter extends ATNSimulator> {
public static final int EOF=-1;
private static final Map<String[], Map<String, Integer>> tokenTypeMapCache =
new WeakHashMap<String[], Map<String, Integer>>();
private static final Map<String[], Map<String, Integer>> ruleIndexMapCache =
new WeakHashMap<String[], Map<String, Integer>>();
@NotNull
private List<ANTLRErrorListener> _listeners =
new CopyOnWriteArrayList<ANTLRErrorListener>() {{
@ -61,13 +69,43 @@ public abstract class Recognizer<Symbol, ATNInterpreter extends ATNSimulator> {
public abstract String[] getRuleNames();
/** Used for xpath, tree pattern compilation */
@NotNull
public Map<String, Integer> getTokenTypeMap() {
throw new UnsupportedOperationException("recognizer implementation must implement this");
String[] tokenNames = getTokenNames();
if (tokenNames == null) {
throw new UnsupportedOperationException("The current recognizer does not provide a list of token names.");
}
synchronized (tokenTypeMapCache) {
Map<String, Integer> result = tokenTypeMapCache.get(tokenNames);
if (result == null) {
result = Utils.toMap(tokenNames);
result.put("EOF", Token.EOF);
result = Collections.unmodifiableMap(result);
tokenTypeMapCache.put(tokenNames, result);
}
return result;
}
}
/** Used for xpath, tree pattern compilation */
@NotNull
public Map<String, Integer> getRuleIndexMap() {
throw new UnsupportedOperationException("recognizer implementation must implement this");
String[] ruleNames = getRuleNames();
if (ruleNames == null) {
throw new UnsupportedOperationException("The current recognizer does not provide a list of rule names.");
}
synchronized (ruleIndexMapCache) {
Map<String, Integer> result = ruleIndexMapCache.get(ruleNames);
if (result == null) {
result = Collections.unmodifiableMap(Utils.toMap(ruleNames));
ruleIndexMapCache.put(ruleNames, result);
}
return result;
}
}
public int getTokenType(String tokenName) {

View File

@ -56,7 +56,6 @@ import org.antlr.v4.runtime.tree.*;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Map;
<parser>
>>
@ -225,13 +224,11 @@ public class <parser.name> extends <superClass> {
public static final String[] tokenNames = {
<parser.tokenNames:{t | <t>}; null="\"\<INVALID>\"", separator=", ", wrap, anchor>
};
public static final Map\<String, Integer> tokenNameToType = Utils.toMap(tokenNames);
public static final int
<parser.rules:{r | RULE_<r.name> = <r.index>}; separator=", ", wrap, anchor>;
public static final String[] ruleNames = {
<parser.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor>
};
public static final Map\<String, Integer> ruleNameToIndex = Utils.toMap(ruleNames);
@Override
public String getGrammarFileName() { return "<parser.grammarFileName; format="java-escape">"; }
@ -248,11 +245,6 @@ public class <parser.name> extends <superClass> {
@Override
public ATN getATN() { return _ATN; }
@Override
public Map\<String, Integer> getTokenTypeMap() { return tokenNameToType; }
@Override
public Map\<String, Integer> getRuleIndexMap() { return ruleNameToIndex; }
<namedActions.members>
<parser:(ctor)()>
<funcs; separator="\n">
@ -849,7 +841,6 @@ import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
import java.util.Map;
<lexer>
>>
@ -871,16 +862,9 @@ public class <lexer.name> extends <superClass> {
"\<INVALID>",
<lexer.tokenNames:{t | <t>}; separator=", ", wrap, anchor>
};
public static final Map\<String, Integer> tokenNameToType = Utils.toMap(tokenNames);
public static final String[] ruleNames = {
<lexer.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor>
};
public static final Map\<String, Integer> ruleNameToIndex = Utils.toMap(ruleNames);
@Override
public Map\<String, Integer> getTokenTypeMap() { return tokenNameToType; }
@Override
public Map\<String, Integer> getRuleIndexMap() { return ruleNameToIndex; }
<namedActions.members>