UNPKG

antlr4ts

Version:

ANTLR 4 runtime for JavaScript written in Typescript

690 lines 27 kB
"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.SingletonPredictionContext = exports.PredictionContext = void 0; // ConvertTo-TS run at 2016-10-04T11:26:35.3812636-07:00 const Array2DHashMap_1 = require("../misc/Array2DHashMap"); const Array2DHashSet_1 = require("../misc/Array2DHashSet"); const Arrays_1 = require("../misc/Arrays"); const MurmurHash_1 = require("../misc/MurmurHash"); const Decorators_1 = require("../Decorators"); const PredictionContextCache_1 = require("./PredictionContextCache"); const assert = require("assert"); const INITIAL_HASH = 1; class PredictionContext { constructor(cachedHashCode) { this.cachedHashCode = cachedHashCode; } static calculateEmptyHashCode() { let hash = MurmurHash_1.MurmurHash.initialize(INITIAL_HASH); hash = MurmurHash_1.MurmurHash.finish(hash, 0); return hash; } static calculateSingleHashCode(parent, returnState) { let hash = MurmurHash_1.MurmurHash.initialize(INITIAL_HASH); hash = MurmurHash_1.MurmurHash.update(hash, parent); hash = MurmurHash_1.MurmurHash.update(hash, returnState); hash = MurmurHash_1.MurmurHash.finish(hash, 2); return hash; } static calculateHashCode(parents, returnStates) { let hash = MurmurHash_1.MurmurHash.initialize(INITIAL_HASH); for (let parent of parents) { hash = MurmurHash_1.MurmurHash.update(hash, parent); } for (let returnState of returnStates) { hash = MurmurHash_1.MurmurHash.update(hash, returnState); } hash = MurmurHash_1.MurmurHash.finish(hash, 2 * parents.length); return hash; } static fromRuleContext(atn, outerContext, fullContext = true) { if (outerContext.isEmpty) { return fullContext ? PredictionContext.EMPTY_FULL : PredictionContext.EMPTY_LOCAL; } let parent; if (outerContext._parent) { parent = PredictionContext.fromRuleContext(atn, outerContext._parent, fullContext); } else { parent = fullContext ? PredictionContext.EMPTY_FULL : PredictionContext.EMPTY_LOCAL; } let state = atn.states[outerContext.invokingState]; let transition = state.transition(0); return parent.getChild(transition.followState.stateNumber); } static addEmptyContext(context) { return context.addEmptyContext(); } static removeEmptyContext(context) { return context.removeEmptyContext(); } static join(context0, context1, contextCache = PredictionContextCache_1.PredictionContextCache.UNCACHED) { if (context0 === context1) { return context0; } if (context0.isEmpty) { return PredictionContext.isEmptyLocal(context0) ? context0 : PredictionContext.addEmptyContext(context1); } else if (context1.isEmpty) { return PredictionContext.isEmptyLocal(context1) ? context1 : PredictionContext.addEmptyContext(context0); } let context0size = context0.size; let context1size = context1.size; if (context0size === 1 && context1size === 1 && context0.getReturnState(0) === context1.getReturnState(0)) { let merged = contextCache.join(context0.getParent(0), context1.getParent(0)); if (merged === context0.getParent(0)) { return context0; } else if (merged === context1.getParent(0)) { return context1; } else { return merged.getChild(context0.getReturnState(0)); } } let count = 0; let parentsList = new Array(context0size + context1size); let returnStatesList = new Array(parentsList.length); let leftIndex = 0; let rightIndex = 0; let canReturnLeft = true; let canReturnRight = true; while (leftIndex < context0size && rightIndex < context1size) { if (context0.getReturnState(leftIndex) === context1.getReturnState(rightIndex)) { parentsList[count] = contextCache.join(context0.getParent(leftIndex), context1.getParent(rightIndex)); returnStatesList[count] = context0.getReturnState(leftIndex); canReturnLeft = canReturnLeft && parentsList[count] === context0.getParent(leftIndex); canReturnRight = canReturnRight && parentsList[count] === context1.getParent(rightIndex); leftIndex++; rightIndex++; } else if (context0.getReturnState(leftIndex) < context1.getReturnState(rightIndex)) { parentsList[count] = context0.getParent(leftIndex); returnStatesList[count] = context0.getReturnState(leftIndex); canReturnRight = false; leftIndex++; } else { assert(context1.getReturnState(rightIndex) < context0.getReturnState(leftIndex)); parentsList[count] = context1.getParent(rightIndex); returnStatesList[count] = context1.getReturnState(rightIndex); canReturnLeft = false; rightIndex++; } count++; } while (leftIndex < context0size) { parentsList[count] = context0.getParent(leftIndex); returnStatesList[count] = context0.getReturnState(leftIndex); leftIndex++; canReturnRight = false; count++; } while (rightIndex < context1size) { parentsList[count] = context1.getParent(rightIndex); returnStatesList[count] = context1.getReturnState(rightIndex); rightIndex++; canReturnLeft = false; count++; } if (canReturnLeft) { return context0; } else if (canReturnRight) { return context1; } if (count < parentsList.length) { parentsList = parentsList.slice(0, count); returnStatesList = returnStatesList.slice(0, count); } if (parentsList.length === 0) { // if one of them was EMPTY_LOCAL, it would be empty and handled at the beginning of the method return PredictionContext.EMPTY_FULL; } else if (parentsList.length === 1) { return new SingletonPredictionContext(parentsList[0], returnStatesList[0]); } else { return new ArrayPredictionContext(parentsList, returnStatesList); } } static isEmptyLocal(context) { return context === PredictionContext.EMPTY_LOCAL; } static getCachedContext(context, contextCache, visited) { if (context.isEmpty) { return context; } let existing = visited.get(context); if (existing) { return existing; } existing = contextCache.get(context); if (existing) { visited.put(context, existing); return existing; } let changed = false; let parents = new Array(context.size); for (let i = 0; i < parents.length; i++) { let parent = PredictionContext.getCachedContext(context.getParent(i), contextCache, visited); if (changed || parent !== context.getParent(i)) { if (!changed) { parents = new Array(context.size); for (let j = 0; j < context.size; j++) { parents[j] = context.getParent(j); } changed = true; } parents[i] = parent; } } if (!changed) { existing = contextCache.putIfAbsent(context, context); visited.put(context, existing != null ? existing : context); return context; } // We know parents.length>0 because context.isEmpty is checked at the beginning of the method. let updated; if (parents.length === 1) { updated = new SingletonPredictionContext(parents[0], context.getReturnState(0)); } else { let returnStates = new Array(context.size); for (let i = 0; i < context.size; i++) { returnStates[i] = context.getReturnState(i); } updated = new ArrayPredictionContext(parents, returnStates, context.hashCode()); } existing = contextCache.putIfAbsent(updated, updated); visited.put(updated, existing || updated); visited.put(context, existing || updated); return updated; } appendSingleContext(returnContext, contextCache) { return this.appendContext(PredictionContext.EMPTY_FULL.getChild(returnContext), contextCache); } getChild(returnState) { return new SingletonPredictionContext(this, returnState); } hashCode() { return this.cachedHashCode; } toStrings(recognizer, currentState, stop = PredictionContext.EMPTY_FULL) { let result = []; outer: for (let perm = 0;; perm++) { let offset = 0; let last = true; let p = this; let stateNumber = currentState; let localBuffer = ""; localBuffer += "["; while (!p.isEmpty && p !== stop) { let index = 0; if (p.size > 0) { let bits = 1; while (((1 << bits) >>> 0) < p.size) { bits++; } let mask = ((1 << bits) >>> 0) - 1; index = (perm >> offset) & mask; last = last && index >= p.size - 1; if (index >= p.size) { continue outer; } offset += bits; } if (recognizer) { if (localBuffer.length > 1) { // first char is '[', if more than that this isn't the first rule localBuffer += " "; } let atn = recognizer.atn; let s = atn.states[stateNumber]; let ruleName = recognizer.ruleNames[s.ruleIndex]; localBuffer += ruleName; } else if (p.getReturnState(index) !== PredictionContext.EMPTY_FULL_STATE_KEY) { if (!p.isEmpty) { if (localBuffer.length > 1) { // first char is '[', if more than that this isn't the first rule localBuffer += " "; } localBuffer += p.getReturnState(index); } } stateNumber = p.getReturnState(index); p = p.getParent(index); } localBuffer += "]"; result.push(localBuffer); if (last) { break; } } return result; } } __decorate([ Decorators_1.Override ], PredictionContext.prototype, "hashCode", null); __decorate([ __param(0, Decorators_1.NotNull), __param(1, Decorators_1.NotNull), __param(2, Decorators_1.NotNull) ], PredictionContext, "join", null); __decorate([ __param(0, Decorators_1.NotNull), __param(1, Decorators_1.NotNull), __param(2, Decorators_1.NotNull) ], PredictionContext, "getCachedContext", null); exports.PredictionContext = PredictionContext; class EmptyPredictionContext extends PredictionContext { constructor(fullContext) { super(PredictionContext.calculateEmptyHashCode()); this.fullContext = fullContext; } get isFullContext() { return this.fullContext; } addEmptyContext() { return this; } removeEmptyContext() { throw new Error("Cannot remove the empty context from itself."); } getParent(index) { throw new Error("index out of bounds"); } getReturnState(index) { throw new Error("index out of bounds"); } findReturnState(returnState) { return -1; } get size() { return 0; } appendSingleContext(returnContext, contextCache) { return contextCache.getChild(this, returnContext); } appendContext(suffix, contextCache) { return suffix; } get isEmpty() { return true; } get hasEmpty() { return true; } equals(o) { return this === o; } toStrings(recognizer, currentState, stop) { return ["[]"]; } } __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "addEmptyContext", null); __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "removeEmptyContext", null); __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "getParent", null); __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "getReturnState", null); __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "findReturnState", null); __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "size", null); __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "appendSingleContext", null); __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "appendContext", null); __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "isEmpty", null); __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "hasEmpty", null); __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "equals", null); __decorate([ Decorators_1.Override ], EmptyPredictionContext.prototype, "toStrings", null); let ArrayPredictionContext = class ArrayPredictionContext extends PredictionContext { constructor(parents, returnStates, hashCode) { super(hashCode || PredictionContext.calculateHashCode(parents, returnStates)); assert(parents.length === returnStates.length); assert(returnStates.length > 1 || returnStates[0] !== PredictionContext.EMPTY_FULL_STATE_KEY, "Should be using PredictionContext.EMPTY instead."); this.parents = parents; this.returnStates = returnStates; } getParent(index) { return this.parents[index]; } getReturnState(index) { return this.returnStates[index]; } findReturnState(returnState) { return Arrays_1.Arrays.binarySearch(this.returnStates, returnState); } get size() { return this.returnStates.length; } get isEmpty() { return false; } get hasEmpty() { return this.returnStates[this.returnStates.length - 1] === PredictionContext.EMPTY_FULL_STATE_KEY; } addEmptyContext() { if (this.hasEmpty) { return this; } let parents2 = this.parents.slice(0); let returnStates2 = this.returnStates.slice(0); parents2.push(PredictionContext.EMPTY_FULL); returnStates2.push(PredictionContext.EMPTY_FULL_STATE_KEY); return new ArrayPredictionContext(parents2, returnStates2); } removeEmptyContext() { if (!this.hasEmpty) { return this; } if (this.returnStates.length === 2) { return new SingletonPredictionContext(this.parents[0], this.returnStates[0]); } else { let parents2 = this.parents.slice(0, this.parents.length - 1); let returnStates2 = this.returnStates.slice(0, this.returnStates.length - 1); return new ArrayPredictionContext(parents2, returnStates2); } } appendContext(suffix, contextCache) { return ArrayPredictionContext.appendContextImpl(this, suffix, new PredictionContext.IdentityHashMap()); } static appendContextImpl(context, suffix, visited) { if (suffix.isEmpty) { if (PredictionContext.isEmptyLocal(suffix)) { if (context.hasEmpty) { return PredictionContext.EMPTY_LOCAL; } throw new Error("what to do here?"); } return context; } if (suffix.size !== 1) { throw new Error("Appending a tree suffix is not yet supported."); } let result = visited.get(context); if (!result) { if (context.isEmpty) { result = suffix; } else { let parentCount = context.size; if (context.hasEmpty) { parentCount--; } let updatedParents = new Array(parentCount); let updatedReturnStates = new Array(parentCount); for (let i = 0; i < parentCount; i++) { updatedReturnStates[i] = context.getReturnState(i); } for (let i = 0; i < parentCount; i++) { updatedParents[i] = ArrayPredictionContext.appendContextImpl(context.getParent(i), suffix, visited); } if (updatedParents.length === 1) { result = new SingletonPredictionContext(updatedParents[0], updatedReturnStates[0]); } else { assert(updatedParents.length > 1); result = new ArrayPredictionContext(updatedParents, updatedReturnStates); } if (context.hasEmpty) { result = PredictionContext.join(result, suffix); } } visited.put(context, result); } return result; } equals(o) { if (this === o) { return true; } else if (!(o instanceof ArrayPredictionContext)) { return false; } if (this.hashCode() !== o.hashCode()) { // can't be same if hash is different return false; } let other = o; return this.equalsImpl(other, new Array2DHashSet_1.Array2DHashSet()); } equalsImpl(other, visited) { let selfWorkList = []; let otherWorkList = []; selfWorkList.push(this); otherWorkList.push(other); while (true) { let currentSelf = selfWorkList.pop(); let currentOther = otherWorkList.pop(); if (!currentSelf || !currentOther) { break; } let operands = new PredictionContextCache_1.PredictionContextCache.IdentityCommutativePredictionContextOperands(currentSelf, currentOther); if (!visited.add(operands)) { continue; } let selfSize = operands.x.size; if (selfSize === 0) { if (!operands.x.equals(operands.y)) { return false; } continue; } let otherSize = operands.y.size; if (selfSize !== otherSize) { return false; } for (let i = 0; i < selfSize; i++) { if (operands.x.getReturnState(i) !== operands.y.getReturnState(i)) { return false; } let selfParent = operands.x.getParent(i); let otherParent = operands.y.getParent(i); if (selfParent.hashCode() !== otherParent.hashCode()) { return false; } if (selfParent !== otherParent) { selfWorkList.push(selfParent); otherWorkList.push(otherParent); } } } return true; } }; __decorate([ Decorators_1.NotNull ], ArrayPredictionContext.prototype, "parents", void 0); __decorate([ Decorators_1.NotNull ], ArrayPredictionContext.prototype, "returnStates", void 0); __decorate([ Decorators_1.Override ], ArrayPredictionContext.prototype, "getParent", null); __decorate([ Decorators_1.Override ], ArrayPredictionContext.prototype, "getReturnState", null); __decorate([ Decorators_1.Override ], ArrayPredictionContext.prototype, "findReturnState", null); __decorate([ Decorators_1.Override ], ArrayPredictionContext.prototype, "size", null); __decorate([ Decorators_1.Override ], ArrayPredictionContext.prototype, "isEmpty", null); __decorate([ Decorators_1.Override ], ArrayPredictionContext.prototype, "hasEmpty", null); __decorate([ Decorators_1.Override ], ArrayPredictionContext.prototype, "addEmptyContext", null); __decorate([ Decorators_1.Override ], ArrayPredictionContext.prototype, "removeEmptyContext", null); __decorate([ Decorators_1.Override ], ArrayPredictionContext.prototype, "appendContext", null); __decorate([ Decorators_1.Override ], ArrayPredictionContext.prototype, "equals", null); ArrayPredictionContext = __decorate([ __param(0, Decorators_1.NotNull) ], ArrayPredictionContext); let SingletonPredictionContext = class SingletonPredictionContext extends PredictionContext { constructor(parent, returnState) { super(PredictionContext.calculateSingleHashCode(parent, returnState)); // assert(returnState != PredictionContext.EMPTY_FULL_STATE_KEY && returnState != PredictionContext.EMPTY_LOCAL_STATE_KEY); this.parent = parent; this.returnState = returnState; } getParent(index) { // assert(index == 0); return this.parent; } getReturnState(index) { // assert(index == 0); return this.returnState; } findReturnState(returnState) { return this.returnState === returnState ? 0 : -1; } get size() { return 1; } get isEmpty() { return false; } get hasEmpty() { return false; } appendContext(suffix, contextCache) { return contextCache.getChild(this.parent.appendContext(suffix, contextCache), this.returnState); } addEmptyContext() { let parents = [this.parent, PredictionContext.EMPTY_FULL]; let returnStates = [this.returnState, PredictionContext.EMPTY_FULL_STATE_KEY]; return new ArrayPredictionContext(parents, returnStates); } removeEmptyContext() { return this; } equals(o) { if (o === this) { return true; } else if (!(o instanceof SingletonPredictionContext)) { return false; } let other = o; if (this.hashCode() !== other.hashCode()) { return false; } return this.returnState === other.returnState && this.parent.equals(other.parent); } }; __decorate([ Decorators_1.NotNull ], SingletonPredictionContext.prototype, "parent", void 0); __decorate([ Decorators_1.Override ], SingletonPredictionContext.prototype, "getParent", null); __decorate([ Decorators_1.Override ], SingletonPredictionContext.prototype, "getReturnState", null); __decorate([ Decorators_1.Override ], SingletonPredictionContext.prototype, "findReturnState", null); __decorate([ Decorators_1.Override ], SingletonPredictionContext.prototype, "size", null); __decorate([ Decorators_1.Override ], SingletonPredictionContext.prototype, "isEmpty", null); __decorate([ Decorators_1.Override ], SingletonPredictionContext.prototype, "hasEmpty", null); __decorate([ Decorators_1.Override ], SingletonPredictionContext.prototype, "appendContext", null); __decorate([ Decorators_1.Override ], SingletonPredictionContext.prototype, "addEmptyContext", null); __decorate([ Decorators_1.Override ], SingletonPredictionContext.prototype, "removeEmptyContext", null); __decorate([ Decorators_1.Override ], SingletonPredictionContext.prototype, "equals", null); SingletonPredictionContext = __decorate([ __param(0, Decorators_1.NotNull) ], SingletonPredictionContext); exports.SingletonPredictionContext = SingletonPredictionContext; (function (PredictionContext) { PredictionContext.EMPTY_LOCAL = new EmptyPredictionContext(false); PredictionContext.EMPTY_FULL = new EmptyPredictionContext(true); PredictionContext.EMPTY_LOCAL_STATE_KEY = -((1 << 31) >>> 0); PredictionContext.EMPTY_FULL_STATE_KEY = ((1 << 31) >>> 0) - 1; class IdentityHashMap extends Array2DHashMap_1.Array2DHashMap { constructor() { super(IdentityEqualityComparator.INSTANCE); } } PredictionContext.IdentityHashMap = IdentityHashMap; class IdentityEqualityComparator { IdentityEqualityComparator() { // intentionally empty } hashCode(obj) { return obj.hashCode(); } equals(a, b) { return a === b; } } IdentityEqualityComparator.INSTANCE = new IdentityEqualityComparator(); __decorate([ Decorators_1.Override ], IdentityEqualityComparator.prototype, "hashCode", null); __decorate([ Decorators_1.Override ], IdentityEqualityComparator.prototype, "equals", null); PredictionContext.IdentityEqualityComparator = IdentityEqualityComparator; })(PredictionContext = exports.PredictionContext || (exports.PredictionContext = {})); //# sourceMappingURL=PredictionContext.js.map