1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.Parser; import org.antlr.v4.runtime.atn.ATN; import org.antlr.v4.runtime.atn.LexerATNSimulator; import org.antlr.v4.runtime.atn.ParserATNSimulator; import org.antlr.v4.runtime.atn.PredictionContextCache; import org.antlr.v4.runtime.dfa.DFA;
import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiConsumer;
import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull;
public class RefreshableParserInitializer<L extends Lexer, P extends Parser> implements BiConsumer<L, P> { private final AtomicReference<ParserAndLexerATNCaches<L, P>> caches;
public RefreshableParserInitializer() { caches = new AtomicReference<>(); }
private ParserAndLexerATNCaches<L, P> buildATNCache(L l, P p) { ATN lexerATN = l.getATN(); ATN parserATN = p.getATN(); return new ParserAndLexerATNCaches(new AntlrATNCacheFields(lexerATN), new AntlrATNCacheFields(parserATN)); }
@Override public void accept(L l, P p) {
ParserAndLexerATNCaches<L, P> newCache = buildATNCache(l, p); ParserAndLexerATNCaches<L, P> oldCaches = caches.getAndSet(newCache); newCache.config(l,p); }
private static final class ParserAndLexerATNCaches<L extends Lexer, P extends Parser> { public ParserAndLexerATNCaches(AntlrATNCacheFields lexer, AntlrATNCacheFields parser) { this.lexer = lexer; this.parser = parser; }
public final AntlrATNCacheFields lexer; public final AntlrATNCacheFields parser;
public void config(L l, P p){ lexer.configureLexer(l); parser.configureParser(p); } }
public static final class AntlrATNCacheFields { private final ATN atn; private final PredictionContextCache predictionContextCache; private final DFA[] decisionToDFA;
public AntlrATNCacheFields(ATN atn) { this.atn = requireNonNull(atn, "atn is null"); this.predictionContextCache = new PredictionContextCache(); this.decisionToDFA = createDecisionToDFA(atn); }
@SuppressWarnings("ObjectEquality") public void configureLexer(Lexer lexer) { requireNonNull(lexer, "lexer is null"); checkArgument(atn == lexer.getATN(), "Lexer ATN mismatch: expected %s, found %s", atn, lexer.getATN()); lexer.setInterpreter(new LexerATNSimulator(lexer, atn, decisionToDFA, predictionContextCache)); }
@SuppressWarnings("ObjectEquality") public void configureParser(Parser parser) { requireNonNull(parser, "parser is null"); checkArgument(atn == parser.getATN(), "Parser ATN mismatch: expected %s, found %s", atn, parser.getATN()); parser.setInterpreter(new ParserATNSimulator(parser, atn, decisionToDFA, predictionContextCache)); }
private static DFA[] createDecisionToDFA(ATN atn) { DFA[] decisionToDFA = new DFA[atn.getNumberOfDecisions()]; for (int i = 0; i < decisionToDFA.length; i++) { decisionToDFA[i] = new DFA(atn.getDecisionState(i), i); } return decisionToDFA; } } }
|