Package org.antlr.v4.runtime.atn

Source Code of org.antlr.v4.runtime.atn.ProfilingATNSimulator

/*
* [The "BSD license"]
*  Copyright (c) 2013 Terence Parr
*  Copyright (c) 2013 Sam Harwell
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*  1. Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*  2. Redistributions in binary form must reproduce the above copyright
*     notice, this list of conditions and the following disclaimer in the
*     documentation and/or other materials provided with the distribution.
*  3. The name of the author may not be used to endorse or promote products
*     derived from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
*  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
*  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
*  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
*  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
*  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package org.antlr.v4.runtime.atn;

import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.dfa.DFAState;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.misc.Nullable;

import java.util.BitSet;

/**
* @since 4.3
*/
public class ProfilingATNSimulator extends ParserATNSimulator {
  protected final DecisionInfo[] decisions;
  protected int numDecisions;

  protected int _sllStopIndex;
  protected int _llStopIndex;

  protected int currentDecision;
  protected DFAState currentState;

   /** At the point of LL failover, we record how SLL would resolve the conflict so that
   *  we can determine whether or not a decision / input pair is context-sensitive.
   *  If LL gives a different result than SLL's predicted alternative, we have a
   *  context sensitivity for sure. The converse is not necessarily true, however.
   *  It's possible that after conflict resolution chooses minimum alternatives,
   *  SLL could get the same answer as LL. Regardless of whether or not the result indicates
   *  an ambiguity, it is not treated as a context sensitivity because LL prediction
   *  was not required in order to produce a correct prediction for this decision and input sequence.
   *  It may in fact still be a context sensitivity but we don't know by looking at the
   *  minimum alternatives for the current input.
    */
  protected int conflictingAltResolvedBySLL;

  public ProfilingATNSimulator(Parser parser) {
    super(parser,
        parser.getInterpreter().atn,
        parser.getInterpreter().decisionToDFA,
        parser.getInterpreter().sharedContextCache);
    numDecisions = atn.decisionToState.size();
    decisions = new DecisionInfo[numDecisions];
    for (int i=0; i<numDecisions; i++) {
      decisions[i] = new DecisionInfo(i);
    }
  }

  @Override
  public int adaptivePredict(TokenStream input, int decision, ParserRuleContext outerContext) {
    try {
      this._sllStopIndex = -1;
      this._llStopIndex = -1;
      this.currentDecision = decision;
      long start = System.nanoTime(); // expensive but useful info
      int alt = super.adaptivePredict(input, decision, outerContext);
      long stop = System.nanoTime();
      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, 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, input, _startIndex, _llStopIndex, true);
        }
      }

      return alt;
    }
    finally {
      this.currentDecision = -1;
    }
  }

  @Override
  protected DFAState getExistingTargetState(DFAState previousD, int t) {
    // this method is called after each time the input position advances
    // during SLL prediction
    _sllStopIndex = _input.index();

    DFAState existingTargetState = super.getExistingTargetState(previousD, t);
    if ( existingTargetState!=null ) {
      decisions[currentDecision].SLL_DFATransitions++; // count only if we transition over a DFA state
      if ( existingTargetState==ERROR ) {
        decisions[currentDecision].errors.add(
            new ErrorInfo(currentDecision, previousD.configs, _input, _startIndex, _sllStopIndex, false)
        );
      }
    }

    currentState = existingTargetState;
    return existingTargetState;
  }

  @Override
  protected DFAState computeTargetState(DFA dfa, DFAState previousD, int t) {
    DFAState state = super.computeTargetState(dfa, previousD, t);
    currentState = state;
    return state;
  }

  @Override
  protected ATNConfigSet computeReachSet(ATNConfigSet closure, int t, boolean fullCtx) {
    if (fullCtx) {
      // this method is called after each time the input position advances
      // during full context prediction
      _llStopIndex = _input.index();
    }

    ATNConfigSet reachConfigs = super.computeReachSet(closure, t, fullCtx);
    if (fullCtx) {
      decisions[currentDecision].LL_ATNTransitions++; // count computation even if error
      if ( reachConfigs!=null ) {
      }
      else { // no reach on current lookahead symbol. ERROR.
        // TODO: does not handle delayed errors per getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule()
        decisions[currentDecision].errors.add(
          new ErrorInfo(currentDecision, closure, _input, _startIndex, _llStopIndex, true)
        );
      }
    }
    else {
      decisions[currentDecision].SLL_ATNTransitions++;
      if ( reachConfigs!=null ) {
      }
      else { // no reach on current lookahead symbol. ERROR.
        decisions[currentDecision].errors.add(
          new ErrorInfo(currentDecision, closure, _input, _startIndex, _sllStopIndex, false)
        );
      }
    }
    return reachConfigs;
  }

  @Override
  protected boolean evalSemanticContext(SemanticContext pred, ParserRuleContext parserCallStack, int alt, boolean fullCtx) {
    boolean result = super.evalSemanticContext(pred, parserCallStack, alt, fullCtx);
    if (!(pred instanceof SemanticContext.PrecedencePredicate)) {
      boolean fullContext = _llStopIndex >= 0;
      int stopIndex = fullContext ? _llStopIndex : _sllStopIndex;
      decisions[currentDecision].predicateEvals.add(
        new PredicateEvalInfo(currentDecision, _input, _startIndex, stopIndex, pred, result, alt, fullCtx)
      );
    }

    return result;
  }

  @Override
  protected void reportAttemptingFullContext(@NotNull DFA dfa, @Nullable BitSet conflictingAlts, @NotNull ATNConfigSet configs, int startIndex, int stopIndex) {
    if ( conflictingAlts!=null ) {
      conflictingAltResolvedBySLL = conflictingAlts.nextSetBit(0);
    }
    else {
      conflictingAltResolvedBySLL = configs.getAlts().nextSetBit(0);
    }
    decisions[currentDecision].LL_Fallback++;
    super.reportAttemptingFullContext(dfa, conflictingAlts, configs, startIndex, stopIndex);
  }

  @Override
  protected void reportContextSensitivity(@NotNull DFA dfa, int prediction, @NotNull ATNConfigSet configs, int startIndex, int stopIndex) {
    if ( prediction != conflictingAltResolvedBySLL ) {
      decisions[currentDecision].contextSensitivities.add(
          new ContextSensitivityInfo(currentDecision, configs, _input, startIndex, stopIndex)
      );
    }
    super.reportContextSensitivity(dfa, prediction, configs, startIndex, stopIndex);
  }

  @Override
  protected void reportAmbiguity(@NotNull DFA dfa, DFAState D, int startIndex, int stopIndex, boolean exact,
                   @Nullable BitSet ambigAlts, @NotNull ATNConfigSet configs)
  {
    int prediction;
    if ( ambigAlts!=null ) {
      prediction = ambigAlts.nextSetBit(0);
    }
    else {
      prediction = configs.getAlts().nextSetBit(0);
    }
    if ( configs.fullCtx && prediction != conflictingAltResolvedBySLL ) {
      // Even though this is an ambiguity we are reporting, we can
      // still detect some context sensitivities.  Both SLL and LL
      // are showing a conflict, hence an ambiguity, but if they resolve
      // to different minimum alternatives we have also identified a
      // context sensitivity.
      decisions[currentDecision].contextSensitivities.add(
          new ContextSensitivityInfo(currentDecision, configs, _input, startIndex, stopIndex)
      );
    }
    decisions[currentDecision].ambiguities.add(
      new AmbiguityInfo(currentDecision, configs, _input, startIndex, stopIndex, configs.fullCtx)
    );
    super.reportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts, configs);
  }

  // ---------------------------------------------------------------------

  public DecisionInfo[] getDecisionInfo() {
    return decisions;
  }
}
TOP

Related Classes of org.antlr.v4.runtime.atn.ProfilingATNSimulator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.