antlr4ts
Version:
ANTLR 4 runtime for JavaScript written in Typescript
266 lines • 14.1 kB
JavaScript
"use strict";
/*!
* Copyright 2016 The ANTLR Project. All rights reserved.
* Licensed under the BSD-3-Clause license. See LICENSE file in the project root for license information.
*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProfilingATNSimulator = void 0;
// ConvertTo-TS run at 2016-10-04T11:26:36.4188352-07:00
const AmbiguityInfo_1 = require("./AmbiguityInfo");
const ATN_1 = require("./ATN");
const ATNSimulator_1 = require("./ATNSimulator");
const ContextSensitivityInfo_1 = require("./ContextSensitivityInfo");
const DecisionInfo_1 = require("./DecisionInfo");
const ErrorInfo_1 = require("./ErrorInfo");
const Decorators_1 = require("../Decorators");
const LookaheadEventInfo_1 = require("./LookaheadEventInfo");
const ParserATNSimulator_1 = require("./ParserATNSimulator");
const PredicateEvalInfo_1 = require("./PredicateEvalInfo");
const SemanticContext_1 = require("./SemanticContext");
const SimulatorState_1 = require("./SimulatorState");
/**
* @since 4.3
*/
class ProfilingATNSimulator extends ParserATNSimulator_1.ParserATNSimulator {
constructor(parser) {
super(parser.interpreter.atn, parser);
this._startIndex = 0;
this._sllStopIndex = 0;
this._llStopIndex = 0;
this.currentDecision = 0;
/** 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.
*/
this.conflictingAltResolvedBySLL = 0;
this.optimize_ll1 = false;
this.reportAmbiguities = true;
this.numDecisions = this.atn.decisionToState.length;
this.decisions = [];
for (let i = 0; i < this.numDecisions; i++) {
this.decisions.push(new DecisionInfo_1.DecisionInfo(i));
}
}
adaptivePredict(input, decision, outerContext, useContext) {
if (useContext !== undefined) {
return super.adaptivePredict(input, decision, outerContext, useContext);
}
try {
this._input = input;
this._startIndex = input.index;
// it's possible for SLL to reach a conflict state without consuming any input
this._sllStopIndex = this._startIndex - 1;
this._llStopIndex = -1;
this.currentDecision = decision;
this.currentState = undefined;
this.conflictingAltResolvedBySLL = ATN_1.ATN.INVALID_ALT_NUMBER;
let start = process.hrtime();
let alt = super.adaptivePredict(input, decision, outerContext);
let stop = process.hrtime();
let nanoseconds = (stop[0] - start[0]) * 1000000000;
if (nanoseconds === 0) {
nanoseconds = stop[1] - start[1];
}
else {
// Add nanoseconds from start to end of that second, plus start of the end second to end
nanoseconds += (1000000000 - start[1]) + stop[1];
}
this.decisions[decision].timeInPrediction += nanoseconds;
this.decisions[decision].invocations++;
let SLL_k = this._sllStopIndex - this._startIndex + 1;
this.decisions[decision].SLL_TotalLook += SLL_k;
this.decisions[decision].SLL_MinLook = this.decisions[decision].SLL_MinLook === 0 ? SLL_k : Math.min(this.decisions[decision].SLL_MinLook, SLL_k);
if (SLL_k > this.decisions[decision].SLL_MaxLook) {
this.decisions[decision].SLL_MaxLook = SLL_k;
this.decisions[decision].SLL_MaxLookEvent =
new LookaheadEventInfo_1.LookaheadEventInfo(decision, undefined, alt, input, this._startIndex, this._sllStopIndex, false);
}
if (this._llStopIndex >= 0) {
let LL_k = this._llStopIndex - this._startIndex + 1;
this.decisions[decision].LL_TotalLook += LL_k;
this.decisions[decision].LL_MinLook = this.decisions[decision].LL_MinLook === 0 ? LL_k : Math.min(this.decisions[decision].LL_MinLook, LL_k);
if (LL_k > this.decisions[decision].LL_MaxLook) {
this.decisions[decision].LL_MaxLook = LL_k;
this.decisions[decision].LL_MaxLookEvent =
new LookaheadEventInfo_1.LookaheadEventInfo(decision, undefined, alt, input, this._startIndex, this._llStopIndex, true);
}
}
return alt;
}
finally {
this._input = undefined;
this.currentDecision = -1;
}
}
getStartState(dfa, input, outerContext, useContext) {
let state = super.getStartState(dfa, input, outerContext, useContext);
this.currentState = state;
return state;
}
computeStartState(dfa, globalContext, useContext) {
let state = super.computeStartState(dfa, globalContext, useContext);
this.currentState = state;
return state;
}
computeReachSet(dfa, previous, t, contextCache) {
if (this._input === undefined) {
throw new Error("Invalid state");
}
let reachState = super.computeReachSet(dfa, previous, t, contextCache);
if (reachState == null) {
// no reach on current lookahead symbol. ERROR.
this.decisions[this.currentDecision].errors.push(new ErrorInfo_1.ErrorInfo(this.currentDecision, previous, this._input, this._startIndex, this._input.index));
}
this.currentState = reachState;
return reachState;
}
getExistingTargetState(previousD, t) {
if (this.currentState === undefined || this._input === undefined) {
throw new Error("Invalid state");
}
// this method is called after each time the input position advances
if (this.currentState.useContext) {
this._llStopIndex = this._input.index;
}
else {
this._sllStopIndex = this._input.index;
}
let existingTargetState = super.getExistingTargetState(previousD, t);
if (existingTargetState != null) {
// this method is directly called by execDFA; must construct a SimulatorState
// to represent the current state for this case
this.currentState = new SimulatorState_1.SimulatorState(this.currentState.outerContext, existingTargetState, this.currentState.useContext, this.currentState.remainingOuterContext);
if (this.currentState.useContext) {
this.decisions[this.currentDecision].LL_DFATransitions++;
}
else {
this.decisions[this.currentDecision].SLL_DFATransitions++; // count only if we transition over a DFA state
}
if (existingTargetState === ATNSimulator_1.ATNSimulator.ERROR) {
let state = new SimulatorState_1.SimulatorState(this.currentState.outerContext, previousD, this.currentState.useContext, this.currentState.remainingOuterContext);
this.decisions[this.currentDecision].errors.push(new ErrorInfo_1.ErrorInfo(this.currentDecision, state, this._input, this._startIndex, this._input.index));
}
}
return existingTargetState;
}
computeTargetState(dfa, s, remainingGlobalContext, t, useContext, contextCache) {
let targetState = super.computeTargetState(dfa, s, remainingGlobalContext, t, useContext, contextCache);
if (useContext) {
this.decisions[this.currentDecision].LL_ATNTransitions++;
}
else {
this.decisions[this.currentDecision].SLL_ATNTransitions++;
}
return targetState;
}
evalSemanticContextImpl(pred, parserCallStack, alt) {
if (this.currentState === undefined || this._input === undefined) {
throw new Error("Invalid state");
}
let result = super.evalSemanticContextImpl(pred, parserCallStack, alt);
if (!(pred instanceof SemanticContext_1.SemanticContext.PrecedencePredicate)) {
let fullContext = this._llStopIndex >= 0;
let stopIndex = fullContext ? this._llStopIndex : this._sllStopIndex;
this.decisions[this.currentDecision].predicateEvals.push(new PredicateEvalInfo_1.PredicateEvalInfo(this.currentState, this.currentDecision, this._input, this._startIndex, stopIndex, pred, result, alt));
}
return result;
}
reportContextSensitivity(dfa, prediction, acceptState, startIndex, stopIndex) {
if (this._input === undefined) {
throw new Error("Invalid state");
}
if (prediction !== this.conflictingAltResolvedBySLL) {
this.decisions[this.currentDecision].contextSensitivities.push(new ContextSensitivityInfo_1.ContextSensitivityInfo(this.currentDecision, acceptState, this._input, startIndex, stopIndex));
}
super.reportContextSensitivity(dfa, prediction, acceptState, startIndex, stopIndex);
}
reportAttemptingFullContext(dfa, conflictingAlts, conflictState, startIndex, stopIndex) {
if (conflictingAlts != null) {
this.conflictingAltResolvedBySLL = conflictingAlts.nextSetBit(0);
}
else {
this.conflictingAltResolvedBySLL = conflictState.s0.configs.getRepresentedAlternatives().nextSetBit(0);
}
this.decisions[this.currentDecision].LL_Fallback++;
super.reportAttemptingFullContext(dfa, conflictingAlts, conflictState, startIndex, stopIndex);
}
reportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts, configs) {
if (this.currentState === undefined || this._input === undefined) {
throw new Error("Invalid state");
}
let prediction;
if (ambigAlts != null) {
prediction = ambigAlts.nextSetBit(0);
}
else {
prediction = configs.getRepresentedAlternatives().nextSetBit(0);
}
if (this.conflictingAltResolvedBySLL !== ATN_1.ATN.INVALID_ALT_NUMBER && prediction !== this.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.
this.decisions[this.currentDecision].contextSensitivities.push(new ContextSensitivityInfo_1.ContextSensitivityInfo(this.currentDecision, this.currentState, this._input, startIndex, stopIndex));
}
this.decisions[this.currentDecision].ambiguities.push(new AmbiguityInfo_1.AmbiguityInfo(this.currentDecision, this.currentState, ambigAlts, this._input, startIndex, stopIndex));
super.reportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts, configs);
}
// ---------------------------------------------------------------------
getDecisionInfo() {
return this.decisions;
}
getCurrentState() {
return this.currentState;
}
}
__decorate([
Decorators_1.Override,
__param(0, Decorators_1.NotNull)
], ProfilingATNSimulator.prototype, "adaptivePredict", null);
__decorate([
Decorators_1.Override
], ProfilingATNSimulator.prototype, "getStartState", null);
__decorate([
Decorators_1.Override
], ProfilingATNSimulator.prototype, "computeStartState", null);
__decorate([
Decorators_1.Override
], ProfilingATNSimulator.prototype, "computeReachSet", null);
__decorate([
Decorators_1.Override
], ProfilingATNSimulator.prototype, "getExistingTargetState", null);
__decorate([
Decorators_1.Override
], ProfilingATNSimulator.prototype, "computeTargetState", null);
__decorate([
Decorators_1.Override
], ProfilingATNSimulator.prototype, "evalSemanticContextImpl", null);
__decorate([
Decorators_1.Override
], ProfilingATNSimulator.prototype, "reportContextSensitivity", null);
__decorate([
Decorators_1.Override
], ProfilingATNSimulator.prototype, "reportAttemptingFullContext", null);
__decorate([
Decorators_1.Override,
__param(0, Decorators_1.NotNull), __param(5, Decorators_1.NotNull), __param(6, Decorators_1.NotNull)
], ProfilingATNSimulator.prototype, "reportAmbiguity", null);
exports.ProfilingATNSimulator = ProfilingATNSimulator;
//# sourceMappingURL=ProfilingATNSimulator.js.map