UNPKG

bitmark-grammar

Version:
154 lines (126 loc) 4.65 kB
/*! * 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. */ // ConvertTo-TS run at 2016-10-04T11:26:35.6390614-07:00 import { Array2DHashMap } from "../misc/Array2DHashMap"; import { Override } from "../Decorators"; import { JavaMap } from "../misc/Stubs"; import { ObjectEqualityComparator } from "../misc/ObjectEqualityComparator"; import { PredictionContext } from "./PredictionContext"; import * as assert from "assert"; /** Used to cache {@link PredictionContext} objects. Its used for the shared * context cash associated with contexts in DFA states. This cache * can be used for both lexers and parsers. * * @author Sam Harwell */ export class PredictionContextCache { public static UNCACHED: PredictionContextCache = new PredictionContextCache(false); private contexts: JavaMap<PredictionContext, PredictionContext> = new Array2DHashMap<PredictionContext, PredictionContext>(ObjectEqualityComparator.INSTANCE); private childContexts: JavaMap<PredictionContextCache.PredictionContextAndInt, PredictionContext> = new Array2DHashMap<PredictionContextCache.PredictionContextAndInt, PredictionContext>(ObjectEqualityComparator.INSTANCE); private joinContexts: JavaMap<PredictionContextCache.IdentityCommutativePredictionContextOperands, PredictionContext> = new Array2DHashMap<PredictionContextCache.IdentityCommutativePredictionContextOperands, PredictionContext>(ObjectEqualityComparator.INSTANCE); private enableCache: boolean; constructor(enableCache: boolean = true) { this.enableCache = enableCache; } public getAsCached(context: PredictionContext): PredictionContext { if (!this.enableCache) { return context; } let result = this.contexts.get(context); if (!result) { result = context; this.contexts.put(context, context); } return result; } public getChild(context: PredictionContext, invokingState: number): PredictionContext { if (!this.enableCache) { return context.getChild(invokingState); } let operands: PredictionContextCache.PredictionContextAndInt = new PredictionContextCache.PredictionContextAndInt(context, invokingState); let result = this.childContexts.get(operands); if (!result) { result = context.getChild(invokingState); result = this.getAsCached(result); this.childContexts.put(operands, result); } return result; } public join(x: PredictionContext, y: PredictionContext): PredictionContext { if (!this.enableCache) { return PredictionContext.join(x, y, this); } let operands: PredictionContextCache.IdentityCommutativePredictionContextOperands = new PredictionContextCache.IdentityCommutativePredictionContextOperands(x, y); let result = this.joinContexts.get(operands); if (result) { return result; } result = PredictionContext.join(x, y, this); result = this.getAsCached(result); this.joinContexts.put(operands, result); return result; } } export namespace PredictionContextCache { export class PredictionContextAndInt { private obj: PredictionContext; private value: number; constructor(obj: PredictionContext, value: number) { this.obj = obj; this.value = value; } @Override public equals(obj: any): boolean { if (!(obj instanceof PredictionContextAndInt)) { return false; } else if (obj === this) { return true; } let other: PredictionContextAndInt = obj; return this.value === other.value && (this.obj === other.obj || (this.obj != null && this.obj.equals(other.obj))); } @Override public hashCode(): number { let hashCode: number = 5; hashCode = 7 * hashCode + (this.obj != null ? this.obj.hashCode() : 0); hashCode = 7 * hashCode + this.value; return hashCode; } } export class IdentityCommutativePredictionContextOperands { private _x: PredictionContext; private _y: PredictionContext; constructor(x: PredictionContext, y: PredictionContext) { assert(x != null); assert(y != null); this._x = x; this._y = y; } get x(): PredictionContext { return this._x; } get y(): PredictionContext { return this._y; } @Override public equals(o: any): boolean { if (!(o instanceof IdentityCommutativePredictionContextOperands)) { return false; } else if (this === o) { return true; } let other: IdentityCommutativePredictionContextOperands = o; return (this._x === other._x && this._y === other._y) || (this._x === other._y && this._y === other._x); } @Override public hashCode(): number { return this._x.hashCode() ^ this._y.hashCode(); } } }