/* * Copyright (c) 2014 Sam Harwell, Tunnel Vision Laboratories LLC * All rights reserved. * * The source code of this document is proprietary work, and is not licensed for * distribution. For information about licensing, contact Sam Harwell at: * sam@tunnelvisionlabs.com */ package org.antlr.works.editor.grammar.debugger; import java.util.BitSet; import org.antlr.runtime.Token; import org.antlr.v4.runtime.Parser; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.TokenStream; import org.antlr.v4.runtime.atn.ATN; import org.antlr.v4.runtime.atn.ParserATNSimulator; import org.antlr.v4.runtime.atn.PredictionContextCache; import org.antlr.v4.runtime.atn.SimulatorState; import org.antlr.v4.runtime.dfa.DFA; import org.antlr.v4.runtime.dfa.DFAState; import org.antlr.v4.runtime.misc.Tuple2; /** * * @author Sam Harwell */ public class StatisticsParserATNSimulator extends ParserATNSimulator { public final long[] decisionInvocations; public final long[] fullContextFallback; public final long[] nonSll; public final long[] ambiguousResult; public final long[] totalTransitions; public final long[] computedTransitions; public final long[] fullContextTransitions; public final long[] totalLookaheadSll; public final long[] totalLookaheadLl; public final long[] minLookaheadSll; public final long[] maxLookaheadSll; public final long[] minLookaheadLl; public final long[] maxLookaheadLl; private int decision; private boolean reportedLookahead; public StatisticsParserATNSimulator(ATN atn) { super(atn); decisionInvocations = new long[atn.decisionToState.size()]; fullContextFallback = new long[atn.decisionToState.size()]; nonSll = new long[atn.decisionToState.size()]; ambiguousResult = new long[atn.decisionToState.size()]; totalTransitions = new long[atn.decisionToState.size()]; computedTransitions = new long[atn.decisionToState.size()]; fullContextTransitions = new long[atn.decisionToState.size()]; totalLookaheadSll = new long[atn.decisionToState.size()]; totalLookaheadLl = new long[atn.decisionToState.size()]; minLookaheadSll = new long[atn.decisionToState.size()]; maxLookaheadSll = new long[atn.decisionToState.size()]; minLookaheadLl = new long[atn.decisionToState.size()]; maxLookaheadLl = new long[atn.decisionToState.size()]; for (int i = 0; i < minLookaheadSll.length; i++) { minLookaheadSll[i] = Long.MAX_VALUE; minLookaheadLl[i] = Long.MAX_VALUE; maxLookaheadSll[i] = Long.MIN_VALUE; maxLookaheadLl[i] = Long.MIN_VALUE; } } public StatisticsParserATNSimulator(Parser parser, ATN atn) { super(parser, atn); decisionInvocations = new long[atn.decisionToState.size()]; fullContextFallback = new long[atn.decisionToState.size()]; nonSll = new long[atn.decisionToState.size()]; ambiguousResult = new long[atn.decisionToState.size()]; totalTransitions = new long[atn.decisionToState.size()]; computedTransitions = new long[atn.decisionToState.size()]; fullContextTransitions = new long[atn.decisionToState.size()]; totalLookaheadSll = new long[atn.decisionToState.size()]; totalLookaheadLl = new long[atn.decisionToState.size()]; minLookaheadSll = new long[atn.decisionToState.size()]; maxLookaheadSll = new long[atn.decisionToState.size()]; minLookaheadLl = new long[atn.decisionToState.size()]; maxLookaheadLl = new long[atn.decisionToState.size()]; for (int i = 0; i < minLookaheadSll.length; i++) { minLookaheadSll[i] = Long.MAX_VALUE; minLookaheadLl[i] = Long.MAX_VALUE; maxLookaheadSll[i] = Long.MIN_VALUE; maxLookaheadLl[i] = Long.MIN_VALUE; } } @Override public int adaptivePredict(TokenStream input, int decision, ParserRuleContext outerContext) { try { this.decision = decision; this.reportedLookahead = false; decisionInvocations[decision]++; return super.adaptivePredict(input, decision, outerContext); } finally { this.decision = -1; } } @Override protected int execDFA(DFA dfa, TokenStream input, int startIndex, SimulatorState state) { int result = super.execDFA(dfa, input, startIndex, state); if (!reportedLookahead) { int stopIndex = input.index(); int k; if (startIndex == stopIndex) { k = 1; } else if (startIndex == stopIndex - 1) { k = 2; } else { k = 0; for (int i = startIndex; i <= stopIndex; i++) { input.seek(i); if (input.LT(1).getChannel() == Token.DEFAULT_CHANNEL) { k++; } } } if (!state.useContext) { totalLookaheadSll[dfa.decision] += k; minLookaheadSll[dfa.decision] = Math.min(minLookaheadSll[dfa.decision], k); maxLookaheadSll[dfa.decision] = Math.max(maxLookaheadSll[dfa.decision], k); } else { totalLookaheadLl[dfa.decision] += k; minLookaheadLl[dfa.decision] = Math.min(minLookaheadLl[dfa.decision], k); maxLookaheadLl[dfa.decision] = Math.max(maxLookaheadLl[dfa.decision], k); } reportedLookahead = true; } return result; } @Override protected int execATN(DFA dfa, TokenStream input, int startIndex, SimulatorState initialState) { int result = super.execATN(dfa, input, startIndex, initialState); if (!reportedLookahead) { int stopIndex = input.index(); int k; if (startIndex == stopIndex) { k = 1; } else if (startIndex == stopIndex - 1) { k = 2; } else { k = 0; for (int i = startIndex; i <= stopIndex; i++) { input.seek(i); if (input.LT(1).getChannel() == Token.DEFAULT_CHANNEL) { k++; } } } if (!initialState.useContext) { totalLookaheadSll[dfa.decision] += k; minLookaheadSll[dfa.decision] = Math.min(minLookaheadSll[dfa.decision], k); maxLookaheadSll[dfa.decision] = Math.max(maxLookaheadSll[dfa.decision], k); } else { totalLookaheadLl[dfa.decision] += k; minLookaheadLl[dfa.decision] = Math.min(minLookaheadLl[dfa.decision], k); maxLookaheadLl[dfa.decision] = Math.max(maxLookaheadLl[dfa.decision], k); } reportedLookahead = true; } return result; } @Override protected DFAState getExistingTargetState(DFAState previousD, int t) { totalTransitions[decision]++; return super.getExistingTargetState(previousD, t); } @Override protected Tuple2<DFAState, ParserRuleContext> computeTargetState(DFA dfa, DFAState s, ParserRuleContext remainingGlobalContext, int t, boolean useContext, PredictionContextCache contextCache) { computedTransitions[decision]++; return super.computeTargetState(dfa, s, remainingGlobalContext, t, useContext, contextCache); } @Override protected SimulatorState computeReachSet(DFA dfa, SimulatorState previous, int t, PredictionContextCache contextCache) { if (previous.useContext) { totalTransitions[decision]++; computedTransitions[decision]++; fullContextTransitions[decision]++; } return super.computeReachSet(dfa, previous, t, contextCache); } @Override protected void reportAttemptingFullContext(DFA dfa, BitSet conflictingAlts, SimulatorState conflictState, int startIndex, int stopIndex) { super.reportAttemptingFullContext(dfa, conflictingAlts, conflictState, startIndex, stopIndex); int k; if (startIndex == stopIndex) { k = 1; } else if (startIndex == stopIndex - 1) { k = 2; } else { k = 0; for (int i = startIndex; i <= stopIndex; i++) { parser.getInputStream().seek(i); if (parser.getInputStream().LT(1).getChannel() == Token.DEFAULT_CHANNEL) { k++; } } } fullContextFallback[dfa.decision]++; totalLookaheadSll[dfa.decision] += k; minLookaheadSll[dfa.decision] = Math.min(minLookaheadSll[dfa.decision], k); maxLookaheadSll[dfa.decision] = Math.max(maxLookaheadSll[dfa.decision], k); } }