using System;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
public class ProfilingATNSimulator : ParserATNSimulator
{
protected readonly DecisionInfo[] decisions;
protected int numDecisions;
protected int sllStopIndex;
protected int llStopIndex;
protected int currentDecision;
protected DFAState currentState;
protected int conflictingAltResolvedBySLL;
public ProfilingATNSimulator(Parser parser)
: base(parser,
parser.Interpreter.atn,
parser.Interpreter.decisionToDFA,
parser.Interpreter.getSharedContextCache())
{
numDecisions = atn.decisionToState.Count;
decisions = new DecisionInfo[numDecisions];
for (int i = 0; i < numDecisions; i++)
{
decisions[i] = new DecisionInfo(i);
}
}
public override int AdaptivePredict(ITokenStream input, int decision, ParserRuleContext outerContext)
{
try
{
this.sllStopIndex = -1;
this.llStopIndex = -1;
this.currentDecision = decision;
long start = DateTime.Now.ToFileTime(); int alt = base.AdaptivePredict(input, decision, outerContext);
long stop = DateTime.Now.ToFileTime();
decisions[decision].timeInPrediction += (stop - start);
decisions[decision].invocations++;
int SLL_k = sllStopIndex - startIndex + 1;
decisions[decision].SLL_TotalLook += SLL_k;
decisions[decision].SLL_MinLook = decisions[decision].SLL_MinLook == 0 ? SLL_k : Math.Min(decisions[decision].SLL_MinLook, SLL_k);
if (SLL_k > decisions[decision].SLL_MaxLook)
{
decisions[decision].SLL_MaxLook = SLL_k;
decisions[decision].SLL_MaxLookEvent =
new LookaheadEventInfo(decision, null, alt, input, startIndex, sllStopIndex, false);
}
if (llStopIndex >= 0)
{
int LL_k = llStopIndex - startIndex + 1;
decisions[decision].LL_TotalLook += LL_k;
decisions[decision].LL_MinLook = decisions[decision].LL_MinLook == 0 ? LL_k : Math.Min(decisions[decision].LL_MinLook, LL_k);
if (LL_k > decisions[decision].LL_MaxLook)
{
decisions[decision].LL_MaxLook = LL_k;
decisions[decision].LL_MaxLookEvent =
new LookaheadEventInfo(decision, null, alt, input, startIndex, llStopIndex, true);
}
}
return alt;
}
finally
{
this.currentDecision = -1;
}
}
protected override DFAState GetExistingTargetState(DFAState previousD, int t)
{
sllStopIndex = input.Index;
DFAState existingTargetState = base.GetExistingTargetState(previousD, t);
if (existingTargetState != null)
{
decisions[currentDecision].SLL_DFATransitions++; if (existingTargetState == ERROR)
{
decisions[currentDecision].errors.Add(
new ErrorInfo(currentDecision, previousD.configSet, input, startIndex, sllStopIndex, false)
);
}
}
currentState = existingTargetState;
return existingTargetState;
}
protected override DFAState ComputeTargetState(DFA dfa, DFAState previousD, int t)
{
DFAState state = base.ComputeTargetState(dfa, previousD, t);
currentState = state;
return state;
}
protected override ATNConfigSet ComputeReachSet(ATNConfigSet closure, int t, bool fullCtx)
{
if (fullCtx)
{
llStopIndex = input.Index;
}
ATNConfigSet reachConfigs = base.ComputeReachSet(closure, t, fullCtx);
if (fullCtx)
{
decisions[currentDecision].LL_ATNTransitions++; if (reachConfigs != null)
{
}
else { decisions[currentDecision].errors.Add(
new ErrorInfo(currentDecision, closure, input, startIndex, llStopIndex, true)
);
}
}
else {
decisions[currentDecision].SLL_ATNTransitions++;
if (reachConfigs != null)
{
}
else { decisions[currentDecision].errors.Add(
new ErrorInfo(currentDecision, closure, input, startIndex, sllStopIndex, false)
);
}
}
return reachConfigs;
}
protected override bool EvalSemanticContext(SemanticContext pred, ParserRuleContext parserCallStack, int alt, bool fullCtx)
{
bool result = base.EvalSemanticContext(pred, parserCallStack, alt, fullCtx);
if (!(pred is SemanticContext.PrecedencePredicate)) {
bool fullContext = llStopIndex >= 0;
int stopIndex = fullContext ? llStopIndex : sllStopIndex;
decisions[currentDecision].predicateEvals.Add(
new PredicateEvalInfo(currentDecision, input, startIndex, stopIndex, pred, result, alt, fullCtx)
);
}
return result;
}
protected override void ReportAttemptingFullContext(DFA dfa, BitSet conflictingAlts, ATNConfigSet configs, int startIndex, int stopIndex)
{
if (conflictingAlts != null)
{
conflictingAltResolvedBySLL = conflictingAlts.NextSetBit(0);
}
else {
conflictingAltResolvedBySLL = configs.GetAlts().NextSetBit(0);
}
decisions[currentDecision].LL_Fallback++;
base.ReportAttemptingFullContext(dfa, conflictingAlts, configs, startIndex, stopIndex);
}
protected override void ReportContextSensitivity(DFA dfa, int prediction, ATNConfigSet configs, int startIndex, int stopIndex)
{
if (prediction != conflictingAltResolvedBySLL)
{
decisions[currentDecision].contextSensitivities.Add(
new ContextSensitivityInfo(currentDecision, configs, input, startIndex, stopIndex)
);
}
base.ReportContextSensitivity(dfa, prediction, configs, startIndex, stopIndex);
}
protected override void ReportAmbiguity(DFA dfa, DFAState D, int startIndex, int stopIndex, bool exact,
BitSet ambigAlts, ATNConfigSet configs)
{
int prediction;
if (ambigAlts != null)
{
prediction = ambigAlts.NextSetBit(0);
}
else {
prediction = configs.GetAlts().NextSetBit(0);
}
if (configs.fullCtx && prediction != conflictingAltResolvedBySLL)
{
decisions[currentDecision].contextSensitivities.Add( new ContextSensitivityInfo(currentDecision, configs, input, startIndex, stopIndex) );
}
decisions[currentDecision].ambiguities.Add(
new AmbiguityInfo(currentDecision, configs, ambigAlts,
input, startIndex, stopIndex, configs.fullCtx)
);
base.ReportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts, configs);
}
public DecisionInfo[] getDecisionInfo()
{
return decisions;
}
public DFAState getCurrentState()
{
return currentState;
}
}
}