UNPKG

antlr4ng

Version:

Alternative JavaScript/TypeScript runtime for ANTLR4

888 lines (877 loc) 22.9 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/atn/PrecedencePredicateTransition.ts var PrecedencePredicateTransition_exports = {}; __export(PrecedencePredicateTransition_exports, { PrecedencePredicateTransition: () => PrecedencePredicateTransition }); module.exports = __toCommonJS(PrecedencePredicateTransition_exports); // src/utils/MurmurHash.ts var c1 = 3432918353; var c2 = 461845907; var r1 = 15; var r2 = 13; var m = 5; var n = 3864292196; var MurmurHash = class _MurmurHash { static { __name(this, "MurmurHash"); } static defaultSeed = 701; constructor() { } /** * Initialize the hash using the specified {@code seed}. * * @param seed the seed * * @returns the intermediate hash value */ static initialize(seed = _MurmurHash.defaultSeed) { return seed; } static updateFromComparable(hash, value) { return this.update(hash, value?.hashCode() ?? 0); } /** * Update the intermediate hash value for the next input {@code value}. * * @param hash The intermediate hash value. * @param value the value to add to the current hash. * * @returns the updated intermediate hash value */ static update(hash, value) { value = Math.imul(value, c1); value = value << r1 | value >>> 32 - r1; value = Math.imul(value, c2); hash = hash ^ value; hash = hash << r2 | hash >>> 32 - r2; hash = Math.imul(hash, m) + n; return hash; } /** * Apply the final computation steps to the intermediate value {@code hash} * to form the final result of the MurmurHash 3 hash function. * * @param hash The intermediate hash value. * @param entryCount The number of values added to the hash. * * @returns the final hash result */ static finish(hash, entryCount) { hash ^= entryCount * 4; hash ^= hash >>> 16; hash = Math.imul(hash, 2246822507); hash ^= hash >>> 13; hash = Math.imul(hash, 3266489909); hash ^= hash >>> 16; return hash; } /** * An all-in-one convenience method to compute a hash for a single value. * * @param value The value to hash. * @param seed The seed for the hash value. * * @returns The computed hash. */ static hashCode(value, seed) { return _MurmurHash.finish(_MurmurHash.update(seed ?? _MurmurHash.defaultSeed, value), 1); } }; // src/misc/ObjectEqualityComparator.ts var ObjectEqualityComparator = class _ObjectEqualityComparator { static { __name(this, "ObjectEqualityComparator"); } static instance = new _ObjectEqualityComparator(); hashCode(obj) { if (obj == null) { return 0; } return obj.hashCode(); } equals(a, b) { if (a == null) { return b == null; } return a.equals(b); } }; // src/misc/DefaultEqualityComparator.ts var DefaultEqualityComparator = class _DefaultEqualityComparator { static { __name(this, "DefaultEqualityComparator"); } static instance = new _DefaultEqualityComparator(); hashCode(obj) { if (obj == null) { return 0; } return ObjectEqualityComparator.instance.hashCode(obj); } equals(a, b) { if (a == null) { return b == null; } if (typeof a === "string" || typeof a === "number") { return a === b; } return ObjectEqualityComparator.instance.equals(a, b); } }; // src/misc/HashSet.ts var HashSet = class _HashSet { static { __name(this, "HashSet"); } static defaultLoadFactor = 0.75; static initialCapacity = 16; // must be power of 2 comparator; buckets; threshold; /** How many elements in set */ itemCount = 0; constructor(comparatorOrSet, initialCapacity = _HashSet.initialCapacity) { if (comparatorOrSet instanceof _HashSet) { this.comparator = comparatorOrSet.comparator; this.buckets = comparatorOrSet.buckets.slice(0); for (let i = 0; i < this.buckets.length; i++) { const bucket = this.buckets[i]; if (bucket) { this.buckets[i] = bucket.slice(0); } } this.itemCount = comparatorOrSet.itemCount; this.threshold = comparatorOrSet.threshold; } else { this.comparator = comparatorOrSet ?? DefaultEqualityComparator.instance; this.buckets = this.createBuckets(initialCapacity); this.threshold = Math.floor(_HashSet.initialCapacity * _HashSet.defaultLoadFactor); } } /** * Add `o` to set if not there; return existing value if already * there. This method performs the same operation as {@link #add} aside from * the return value. * * @param o the object to add to the set. * * @returns An existing element that equals to `o` if already in set, otherwise `o`. */ getOrAdd(o) { if (this.itemCount > this.threshold) { this.expand(); } const b = this.getBucket(o); let bucket = this.buckets[b]; if (!bucket) { bucket = [o]; this.buckets[b] = bucket; ++this.itemCount; return o; } for (const existing of bucket) { if (this.comparator.equals(existing, o)) { return existing; } } bucket.push(o); ++this.itemCount; return o; } get(o) { if (o == null) { return o; } const b = this.getBucket(o); const bucket = this.buckets[b]; if (!bucket) { return void 0; } for (const e of bucket) { if (this.comparator.equals(e, o)) { return e; } } return void 0; } /** * Removes the specified element from this set if it is present. * * @param o object to be removed from this set, if present. * * @returns `true` if the set contained the specified element. */ remove(o) { if (o == null) { return false; } const b = this.getBucket(o); const bucket = this.buckets[b]; if (!bucket) { return false; } for (let i = 0; i < bucket.length; i++) { const existing = bucket[i]; if (this.comparator.equals(existing, o)) { bucket.splice(i, 1); --this.itemCount; return true; } } return false; } hashCode() { let hash = MurmurHash.initialize(); for (const bucket of this.buckets) { if (bucket == null) { continue; } for (const o of bucket) { if (o == null) { break; } hash = MurmurHash.update(hash, this.comparator.hashCode(o)); } } hash = MurmurHash.finish(hash, this.size); return hash; } equals(o) { if (o === this) { return true; } if (!(o instanceof _HashSet)) { return false; } if (o.size !== this.size) { return false; } return this.containsAll(o); } add(t) { const existing = this.getOrAdd(t); return existing === t; } contains(o) { return this.containsFast(o); } containsFast(obj) { if (obj == null) { return false; } return this.get(obj) !== void 0; } *[Symbol.iterator]() { yield* this.toArray(); } toArray() { const a = new Array(this.size); let i = 0; for (const bucket of this.buckets) { if (bucket == null) { continue; } for (const o of bucket) { if (o == null) { break; } a[i++] = o; } } return a; } containsAll(collection) { if (collection instanceof _HashSet) { for (const bucket of collection.buckets) { if (bucket == null) { continue; } for (const o of bucket) { if (o == null) { break; } if (!this.containsFast(o)) { return false; } } } } else { for (const o of collection) { if (!this.containsFast(o)) { return false; } } } return true; } addAll(c) { let changed = false; for (const o of c) { const existing = this.getOrAdd(o); if (existing !== o) { changed = true; } } return changed; } clear() { this.buckets = this.createBuckets(_HashSet.initialCapacity); this.itemCount = 0; this.threshold = Math.floor(_HashSet.initialCapacity * _HashSet.defaultLoadFactor); } toString() { if (this.size === 0) { return "{}"; } let buf = "{"; let first = true; for (const bucket of this.buckets) { if (bucket == null) { continue; } for (const o of bucket) { if (o == null) { break; } if (first) { first = false; } else { buf += ", "; } buf += o.toString(); } } buf += "}"; return buf; } toTableString() { let buf = ""; for (const bucket of this.buckets) { if (bucket == null) { buf += "null\n"; continue; } buf += "["; let first = true; for (const o of bucket) { if (first) { first = false; } else { buf += " "; } if (o == null) { buf += "_"; } else { buf += o.toString(); } } buf += "]\n"; } return buf; } getBucket(o) { const hash = this.comparator.hashCode(o); const b = hash & this.buckets.length - 1; return b; } expand() { const old = this.buckets; const newCapacity = this.buckets.length * 2; const newTable = this.createBuckets(newCapacity); this.buckets = newTable; this.threshold = Math.floor(newCapacity * _HashSet.defaultLoadFactor); for (const bucket of old) { if (!bucket) { continue; } for (const o of bucket) { const b = this.getBucket(o); let newBucket = this.buckets[b]; if (!newBucket) { newBucket = []; this.buckets[b] = newBucket; } newBucket.push(o); } } } get size() { return this.itemCount; } get isEmpty() { return this.itemCount === 0; } /** * Return an array of `T[]` with length `capacity`. * * @param capacity the length of the array to return * @returns the newly constructed array */ createBuckets(capacity) { return new Array(capacity); } }; // src/utils/helpers.ts var equalArrays = /* @__PURE__ */ __name((a, b) => { if (a === b) { return true; } if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { const left = a[i]; const right = b[i]; if (left === right) { continue; } if (!left || !left.equals(right)) { return false; } } return true; }, "equalArrays"); // src/atn/SemanticContext.ts var SemanticContext = class _SemanticContext { static { __name(this, "SemanticContext"); } cachedHashCode; static andContext(a, b) { if (a === null || a === _SemanticContext.NONE) { return b; } if (b === null || b === _SemanticContext.NONE) { return a; } const result = new AND(a, b); if (result.operands.length === 1) { return result.operands[0]; } return result; } static orContext(a, b) { if (a === null) { return b; } if (b === null) { return a; } if (a === _SemanticContext.NONE || b === _SemanticContext.NONE) { return _SemanticContext.NONE; } const result = new OR(a, b); if (result.operands.length === 1) { return result.operands[0]; } else { return result; } } static filterPrecedencePredicates(set) { const result = []; for (const context of set) { if (context instanceof _SemanticContext.PrecedencePredicate) { result.push(context); } } return result; } /** * Evaluate the precedence predicates for the context and reduce the result. * * @param _parser The parser instance. * @param _parserCallStack The current parser context object. * @returns The simplified semantic context after precedence predicates are * evaluated, which will be one of the following values. * - {@link NONE}: if the predicate simplifies to `true` after * precedence predicates are evaluated. * - `null`: if the predicate simplifies to `false` after * precedence predicates are evaluated. * - `this`: if the semantic context is not changed as a result of * precedence predicate evaluation. * - A non-`null` {@link SemanticContext}: the new simplified * semantic context after precedence predicates are evaluated. */ evalPrecedence(_parser, _parserCallStack) { return this; } }; var AND = class _AND extends SemanticContext { static { __name(this, "AND"); } operands; /** * A semantic context which is true whenever none of the contained contexts * is false */ constructor(a, b) { super(); const operands = new HashSet(); if (a instanceof _AND) { a.operands.forEach((o) => { operands.add(o); }); } else { operands.add(a); } if (b instanceof _AND) { b.operands.forEach((o) => { operands.add(o); }); } else { operands.add(b); } const precedencePredicates = SemanticContext.filterPrecedencePredicates(operands); if (precedencePredicates.length > 0) { let reduced = null; precedencePredicates.forEach((p) => { if (reduced === null || p.precedence < reduced.precedence) { reduced = p; } }); if (reduced) { operands.add(reduced); } } this.operands = operands.toArray(); } equals(other) { if (this === other) { return true; } if (!(other instanceof _AND)) { return false; } return equalArrays(this.operands, other.operands); } hashCode() { if (this.cachedHashCode === void 0) { let hash = MurmurHash.initialize(); for (const operand of this.operands) { hash = MurmurHash.updateFromComparable(hash, operand); } hash = MurmurHash.update(hash, 3813686060); this.cachedHashCode = MurmurHash.finish(hash, this.operands.length + 1); } return this.cachedHashCode; } /** * {@inheritDoc} * * * The evaluation of predicates by this context is short-circuiting, but * unordered. */ evaluate(parser, parserCallStack) { for (const operand of this.operands) { if (!operand.evaluate(parser, parserCallStack)) { return false; } } return true; } evalPrecedence(parser, parserCallStack) { let differs = false; const operands = []; for (const context of this.operands) { const evaluated = context.evalPrecedence(parser, parserCallStack); differs ||= evaluated !== context; if (evaluated === null) { return null; } else if (evaluated !== SemanticContext.NONE) { operands.push(evaluated); } } if (!differs) { return this; } if (operands.length === 0) { return SemanticContext.NONE; } let result = null; operands.forEach((o) => { result = result === null ? o : SemanticContext.andContext(result, o); }); return result; } toString() { const s = this.operands.map((o) => { return o.toString(); }); return (s.length > 3 ? s.slice(3) : s).join("&&"); } }; var OR = class _OR extends SemanticContext { static { __name(this, "OR"); } operands; /** * A semantic context which is true whenever at least one of the contained * contexts is true */ constructor(a, b) { super(); const operands = new HashSet(); if (a instanceof _OR) { a.operands.forEach((o) => { operands.add(o); }); } else { operands.add(a); } if (b instanceof _OR) { b.operands.forEach((o) => { operands.add(o); }); } else { operands.add(b); } const precedencePredicates = SemanticContext.filterPrecedencePredicates(operands); if (precedencePredicates.length > 0) { const s = precedencePredicates.sort((a2, b2) => { return a2.compareTo(b2); }); const reduced = s[s.length - 1]; operands.add(reduced); } this.operands = operands.toArray(); } equals(other) { if (this === other) { return true; } else if (!(other instanceof _OR)) { return false; } else { return equalArrays(this.operands, other.operands); } } hashCode() { if (this.cachedHashCode === void 0) { let hash = MurmurHash.initialize(); for (const operand of this.operands) { hash = MurmurHash.updateFromComparable(hash, operand); } hash = MurmurHash.update(hash, 3383313031); this.cachedHashCode = MurmurHash.finish(hash, this.operands.length + 1); } return this.cachedHashCode; } /** * The evaluation of predicates by this context is short-circuiting, but unordered. */ evaluate(parser, parserCallStack) { for (const operand of this.operands) { if (operand.evaluate(parser, parserCallStack)) { return true; } } return false; } evalPrecedence(parser, parserCallStack) { let differs = false; const operands = []; for (const context of this.operands) { const evaluated = context.evalPrecedence(parser, parserCallStack); differs ||= evaluated !== context; if (evaluated === SemanticContext.NONE) { return SemanticContext.NONE; } else if (evaluated !== null) { operands.push(evaluated); } } if (!differs) { return this; } if (operands.length === 0) { return null; } let result = null; operands.forEach((o) => { result = result === null ? o : SemanticContext.orContext(result, o); }); return result; } toString() { const s = this.operands.map((o) => { return o.toString(); }); return (s.length > 3 ? s.slice(3) : s).join("||"); } }; ((SemanticContext2) => { class Predicate extends SemanticContext2 { static { __name(this, "Predicate"); } ruleIndex; predIndex; isCtxDependent; // e.g., $i ref in pred constructor(ruleIndex, predIndex, isCtxDependent) { super(); this.ruleIndex = ruleIndex ?? -1; this.predIndex = predIndex ?? -1; this.isCtxDependent = isCtxDependent ?? false; } evaluate(parser, outerContext) { const localctx = this.isCtxDependent ? outerContext : null; return parser.sempred(localctx, this.ruleIndex, this.predIndex); } hashCode() { if (this.cachedHashCode === void 0) { let hashCode = MurmurHash.initialize(); hashCode = MurmurHash.update(hashCode, this.ruleIndex); hashCode = MurmurHash.update(hashCode, this.predIndex); hashCode = MurmurHash.update(hashCode, this.isCtxDependent ? 1 : 0); hashCode = MurmurHash.finish(hashCode, 3); this.cachedHashCode = hashCode; } return this.cachedHashCode; } equals(other) { if (this === other) { return true; } return this.ruleIndex === other.ruleIndex && this.predIndex === other.predIndex && this.isCtxDependent === other.isCtxDependent; } toString() { return "{" + this.ruleIndex + ":" + this.predIndex + "}?"; } } SemanticContext2.Predicate = Predicate; class PrecedencePredicate extends SemanticContext2 { static { __name(this, "PrecedencePredicate"); } precedence; constructor(precedence) { super(); this.precedence = precedence ?? 0; } evaluate(parser, outerContext) { return parser.precpred(outerContext, this.precedence); } evalPrecedence(parser, outerContext) { if (parser.precpred(outerContext ?? null, this.precedence)) { return SemanticContext2.NONE; } return null; } compareTo(other) { return this.precedence - other.precedence; } hashCode() { return 31 + this.precedence; } equals(other) { if (this === other) { return true; } return this.precedence === other.precedence; } toString() { return "{" + this.precedence + ">=prec}?"; } } SemanticContext2.PrecedencePredicate = PrecedencePredicate; SemanticContext2.NONE = new Predicate(); })(SemanticContext || (SemanticContext = {})); // src/atn/Transition.ts var Transition = class { static { __name(this, "Transition"); } static INVALID = 0; static EPSILON = 1; static RANGE = 2; static RULE = 3; static PREDICATE = 4; // e.g., {isType(input.LT(1))} static ATOM = 5; static ACTION = 6; static SET = 7; // ~(A|B) or ~atom, wildcard, which convert to next static NOT_SET = 8; static WILDCARD = 9; static PRECEDENCE = 10; /** The target of this transition. */ target; constructor(target) { this.target = target; } /** * Determines if the transition is an "epsilon" transition. * * The default implementation returns `false`. * * @returns `true` if traversing this transition in the ATN does not * consume an input symbol; otherwise, `false` if traversing this * transition consumes (matches) an input symbol. */ get isEpsilon() { return false; } get label() { return null; } toString() { return ""; } }; // src/atn/AbstractPredicateTransition.ts var AbstractPredicateTransition = class extends Transition { static { __name(this, "AbstractPredicateTransition"); } constructor(target) { super(target); } }; // src/atn/PrecedencePredicateTransition.ts var PrecedencePredicateTransition = class extends AbstractPredicateTransition { static { __name(this, "PrecedencePredicateTransition"); } precedence; constructor(target, precedence) { super(target); this.precedence = precedence; } get isEpsilon() { return true; } matches(_symbol, _minVocabSymbol, _maxVocabSymbol) { return false; } getPredicate() { return new SemanticContext.PrecedencePredicate(this.precedence); } get transitionType() { return Transition.PRECEDENCE; } toString() { return this.precedence + " >= _p"; } };