antlr4ng
Version:
Alternative JavaScript/TypeScript runtime for ANTLR4
1,726 lines (1,713 loc) • 485 kB
JavaScript
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/index.ts
var src_exports = {};
__export(src_exports, {
ATN: () => ATN,
ATNConfig: () => ATNConfig,
ATNConfigSet: () => ATNConfigSet,
ATNDeserializer: () => ATNDeserializer,
ATNSerializer: () => ATNSerializer,
ATNSimulator: () => ATNSimulator,
ATNState: () => ATNState,
AbstractParseTreeVisitor: () => AbstractParseTreeVisitor,
AbstractPredicateTransition: () => AbstractPredicateTransition,
ActionTransition: () => ActionTransition,
ArrayPredictionContext: () => ArrayPredictionContext,
AtomTransition: () => AtomTransition,
BailErrorStrategy: () => BailErrorStrategy,
BaseErrorListener: () => BaseErrorListener,
BasicBlockStartState: () => BasicBlockStartState,
BasicState: () => BasicState,
BitSet: () => BitSet,
BlockEndState: () => BlockEndState,
BlockStartState: () => BlockStartState,
BufferedTokenStream: () => BufferedTokenStream,
CannotInvokeStartRuleError: () => CannotInvokeStartRuleError,
CharStream: () => CharStream,
CharStreamImpl: () => CharStreamImpl,
Chunk: () => Chunk,
CodePointTransitions: () => CodePointTransitions,
CommonToken: () => CommonToken,
CommonTokenFactory: () => CommonTokenFactory,
CommonTokenStream: () => CommonTokenStream,
ConsoleErrorListener: () => ConsoleErrorListener,
DFA: () => DFA,
DFASerializer: () => DFASerializer,
DFAState: () => DFAState,
DecisionInfo: () => DecisionInfo,
DecisionState: () => DecisionState,
DefaultErrorStrategy: () => DefaultErrorStrategy,
DiagnosticErrorListener: () => DiagnosticErrorListener,
DoubleDict: () => DoubleDict,
EmptyPredictionContext: () => EmptyPredictionContext,
EpsilonTransition: () => EpsilonTransition,
ErrorNode: () => ErrorNode,
FailedPredicateException: () => FailedPredicateException,
HashMap: () => HashMap,
HashSet: () => HashSet,
InputMismatchException: () => InputMismatchException,
IntStream: () => IntStream,
InterpreterDataReader: () => InterpreterDataReader,
InterpreterRuleContext: () => InterpreterRuleContext,
Interval: () => Interval,
IntervalSet: () => IntervalSet,
LL1Analyzer: () => LL1Analyzer,
Lexer: () => Lexer,
LexerATNConfig: () => LexerATNConfig,
LexerATNSimulator: () => LexerATNSimulator,
LexerActionExecutor: () => LexerActionExecutor,
LexerActionType: () => LexerActionType,
LexerChannelAction: () => LexerChannelAction,
LexerCustomAction: () => LexerCustomAction,
LexerDFASerializer: () => LexerDFASerializer,
LexerIndexedCustomAction: () => LexerIndexedCustomAction,
LexerInterpreter: () => LexerInterpreter,
LexerModeAction: () => LexerModeAction,
LexerMoreAction: () => LexerMoreAction,
LexerNoViableAltException: () => LexerNoViableAltException,
LexerPopModeAction: () => LexerPopModeAction,
LexerPushModeAction: () => LexerPushModeAction,
LexerSkipAction: () => LexerSkipAction,
LexerTypeAction: () => LexerTypeAction,
ListTokenSource: () => ListTokenSource,
LoopEndState: () => LoopEndState,
MurmurHash: () => MurmurHash,
NoViableAltException: () => NoViableAltException,
NotSetTransition: () => NotSetTransition,
OrderedATNConfigSet: () => OrderedATNConfigSet,
OrderedHashMap: () => OrderedHashMap,
OrderedHashSet: () => OrderedHashSet,
ParseCancellationException: () => ParseCancellationException,
ParseInfo: () => ParseInfo,
ParseTreeMatch: () => ParseTreeMatch,
ParseTreePattern: () => ParseTreePattern,
ParseTreePatternMatcher: () => ParseTreePatternMatcher,
ParseTreeWalker: () => ParseTreeWalker,
Parser: () => Parser,
ParserATNSimulator: () => ParserATNSimulator,
ParserInterpreter: () => ParserInterpreter,
ParserRuleContext: () => ParserRuleContext,
PlusBlockStartState: () => PlusBlockStartState,
PlusLoopbackState: () => PlusLoopbackState,
PrecedencePredicateTransition: () => PrecedencePredicateTransition,
PredPrediction: () => PredPrediction,
PredicateTransition: () => PredicateTransition,
PredictionContext: () => PredictionContext,
PredictionContextCache: () => PredictionContextCache,
PredictionMode: () => PredictionMode,
ProfilingATNSimulator: () => ProfilingATNSimulator,
ProxyErrorListener: () => ProxyErrorListener,
RangeTransition: () => RangeTransition,
RecognitionException: () => RecognitionException,
Recognizer: () => Recognizer,
RuleStartState: () => RuleStartState,
RuleStopState: () => RuleStopState,
RuleTagToken: () => RuleTagToken,
RuleTransition: () => RuleTransition,
RuntimeMetaData: () => RuntimeMetaData,
SemanticContext: () => SemanticContext,
SetTransition: () => SetTransition,
SingletonPredictionContext: () => SingletonPredictionContext,
StarBlockStartState: () => StarBlockStartState,
StarLoopEntryState: () => StarLoopEntryState,
StarLoopbackState: () => StarLoopbackState,
StartRuleDoesNotConsumeFullPatternError: () => StartRuleDoesNotConsumeFullPatternError,
TagChunk: () => TagChunk,
TerminalNode: () => TerminalNode,
TextChunk: () => TextChunk,
Token: () => Token,
TokenStreamRewriter: () => TokenStreamRewriter,
TokenTagToken: () => TokenTagToken,
TokensStartState: () => TokensStartState,
TraceListener: () => TraceListener,
Transition: () => Transition,
Trees: () => Trees,
UnbufferedTokenStream: () => UnbufferedTokenStream,
Vocabulary: () => Vocabulary,
WildcardTransition: () => WildcardTransition,
XPath: () => XPath,
XPathElement: () => XPathElement,
XPathLexer: () => XPathLexer,
XPathLexerErrorListener: () => XPathLexerErrorListener,
XPathRuleAnywhereElement: () => XPathRuleAnywhereElement,
XPathRuleElement: () => XPathRuleElement,
XPathTokenAnywhereElement: () => XPathTokenAnywhereElement,
XPathTokenElement: () => XPathTokenElement,
XPathWildcardAnywhereElement: () => XPathWildcardAnywhereElement,
XPathWildcardElement: () => XPathWildcardElement,
arrayToString: () => arrayToString,
combineCommonParents: () => combineCommonParents,
createSingletonPredictionContext: () => createSingletonPredictionContext,
equalArrays: () => equalArrays,
equalNumberArrays: () => equalNumberArrays,
escapeWhitespace: () => escapeWhitespace,
getCachedPredictionContext: () => getCachedPredictionContext,
isComparable: () => isComparable,
isToken: () => isToken,
isWritableToken: () => isWritableToken,
merge: () => merge,
mergeRoot: () => mergeRoot,
mergeSingletons: () => mergeSingletons,
predictionContextFromRuleContext: () => predictionContextFromRuleContext
});
module.exports = __toCommonJS(src_exports);
// src/IntStream.ts
var IntStream;
((IntStream2) => {
IntStream2.EOF = -1;
IntStream2.UNKNOWN_SOURCE_NAME = "<unknown>";
})(IntStream || (IntStream = {}));
// src/Token.ts
var Token;
((Token2) => {
Token2.INVALID_TYPE = 0;
Token2.EPSILON = -2;
Token2.MIN_USER_TOKEN_TYPE = 1;
Token2.EOF = IntStream.EOF;
Token2.DEFAULT_CHANNEL = 0;
Token2.HIDDEN_CHANNEL = 1;
Token2.MIN_USER_CHANNEL_VALUE = 2;
})(Token || (Token = {}));
var isToken = /* @__PURE__ */ __name((candidate) => {
const token = candidate;
return token.tokenSource !== void 0 && token.channel !== void 0;
}, "isToken");
// src/misc/BitSet.ts
var BitSet = class {
static {
__name(this, "BitSet");
}
data;
/**
* Creates a new bit set. All bits are initially `false`.
*
* @param data Optional initial data.
*/
constructor(data) {
if (data) {
this.data = new Uint32Array(data.map((value) => {
return value >>> 0;
}));
} else {
this.data = new Uint32Array(1);
}
}
/**
* @returns an iterator over all set bits.
*/
[Symbol.iterator]() {
const length = this.data.length;
let currentIndex = 0;
let currentWord = this.data[currentIndex];
const words = this.data;
return {
[Symbol.iterator]() {
return this;
},
next: /* @__PURE__ */ __name(() => {
while (currentIndex < length) {
if (currentWord !== 0) {
const t = currentWord & -currentWord;
const value = (currentIndex << 5) + this.bitCount(t - 1);
currentWord ^= t;
return { done: false, value };
} else {
currentIndex++;
if (currentIndex < length) {
currentWord = words[currentIndex];
}
}
}
return { done: true, value: void 0 };
}, "next")
};
}
/**
* Sets a single bit or all of the bits in this `BitSet` to `false`.
*
* @param index the index of the bit to be cleared, or undefined to clear all bits.
*/
clear(index) {
if (index === void 0) {
this.data = new Uint32Array();
} else {
this.resize(index);
this.data[index >>> 5] &= ~(1 << index);
}
}
/**
* Performs a logical **OR** of this bit set with the bit set argument. This bit set is modified so that a bit in it
* has the value `true` if and only if it either already had the value `true` or the corresponding bit in the bit
* set argument has the value `true`.
*
* @param set the bit set to be ORed with.
*/
or(set) {
const minCount = Math.min(this.data.length, set.data.length);
for (let k = 0; k < minCount; ++k) {
this.data[k] |= set.data[k];
}
if (this.data.length < set.data.length) {
this.resize((set.data.length << 5) - 1);
const c = set.data.length;
for (let k = minCount; k < c; ++k) {
this.data[k] = set.data[k];
}
}
}
/**
* Returns the value of the bit with the specified index. The value is `true` if the bit with the index `bitIndex`
* is currently set in this `BitSet`; otherwise, the result is `false`.
*
* @param index the bit index
*
* @returns the value of the bit with the specified index.
*/
get(index) {
if (index < 0) {
throw new RangeError("index cannot be negative");
}
const slot = index >>> 5;
if (slot >= this.data.length) {
return false;
}
return (this.data[slot] & 1 << index % 32) !== 0;
}
/**
* @returns the number of set bits.
*/
get length() {
let result = 0;
const c = this.data.length;
const w = this.data;
for (let i = 0; i < c; i++) {
result += this.bitCount(w[i]);
}
return result;
}
/**
* @returns an array with indices of set bits.
*/
values() {
const result = new Array(this.length);
let pos = 0;
const length = this.data.length;
for (let k = 0; k < length; ++k) {
let w = this.data[k];
while (w !== 0) {
const t = w & -w;
result[pos++] = (k << 5) + this.bitCount(t - 1);
w ^= t;
}
}
return result;
}
/**
* @returns the index of the first bit that is set to `true` that occurs on or after the specified starting index.
* If no such bit exists then undefined is returned.
*
* @param fromIndex the index to start checking from (inclusive)
*/
nextSetBit(fromIndex) {
if (fromIndex < 0) {
throw new RangeError("index cannot be negative");
}
for (const index of this) {
if (index >= fromIndex) {
return index;
}
}
return void 0;
}
/**
* Sets the bit at the specified index to `true`.
*
* @param index a bit index
*/
set(index) {
if (index < 0) {
throw new RangeError("index cannot be negative");
}
this.resize(index);
this.data[index >>> 5] |= 1 << index % 32;
}
/**
* @returns a string representation of this bit set.
*/
toString() {
return "{" + this.values().join(", ") + "}";
}
resize(index) {
const count = index + 32 >>> 5;
if (count <= this.data.length) {
return;
}
const data = new Uint32Array(count);
data.set(this.data);
data.fill(0, this.data.length);
this.data = data;
}
bitCount(v) {
v = v - (v >> 1 & 1431655765);
v = (v & 858993459) + (v >> 2 & 858993459);
v = v + (v >> 4) & 252645135;
v = v + (v >> 8);
v = v + (v >> 16);
return v & 63;
}
};
// 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/misc/Interval.ts
var Interval = class _Interval {
static {
__name(this, "Interval");
}
static INVALID_INTERVAL = new _Interval(-1, -2);
static INTERVAL_POOL_MAX_VALUE = 1e3;
static cache = [];
start;
stop;
cachedHashCode;
constructor(start, stop) {
this.start = start;
this.stop = stop;
this.cachedHashCode = Math.imul(651 + start, 31) + stop;
}
/**
* Creates a new interval from the given values.
*
* Interval objects are used readonly so share all with the
* same single value a==b up to some max size. Use an array as a perfect hash.
* Return shared object for 0..INTERVAL_POOL_MAX_VALUE or a new
* Interval object with a..a in it. On Java.g4, 218623 IntervalSets
* have a..a (set with 1 element).
*
* @param a The start of the interval.
* @param b The end of the interval (inclusive).
*
* @returns A cached or new interval.
*/
static of(a, b) {
if (a !== b || a < 0 || a > _Interval.INTERVAL_POOL_MAX_VALUE) {
return new _Interval(a, b);
}
if (!_Interval.cache[a]) {
_Interval.cache[a] = new _Interval(a, a);
}
return _Interval.cache[a];
}
equals(o) {
return this.start === o.start && this.stop === o.stop;
}
hashCode() {
return this.cachedHashCode;
}
/** Does this start completely before other? Disjoint */
startsBeforeDisjoint(other) {
return this.start < other.start && this.stop < other.start;
}
/** Does this start at or before other? Nondisjoint */
startsBeforeNonDisjoint(other) {
return this.start <= other.start && this.stop >= other.start;
}
/** Does this.start start after other.stop? May or may not be disjoint */
startsAfter(other) {
return this.start > other.start;
}
/** Does this start completely after other? Disjoint */
startsAfterDisjoint(other) {
return this.start > other.stop;
}
/** Does this start after other? NonDisjoint */
startsAfterNonDisjoint(other) {
return this.start > other.start && this.start <= other.stop;
}
/** Are both ranges disjoint? I.e., no overlap? */
disjoint(other) {
return this.startsBeforeDisjoint(other) || this.startsAfterDisjoint(other);
}
/** Are two intervals adjacent such as 0..41 and 42..42? */
adjacent(other) {
return this.start === other.stop + 1 || this.stop === other.start - 1;
}
properlyContains(other) {
return other.start >= this.start && other.stop <= this.stop;
}
/** Return the interval computed from combining this and other */
union(other) {
return _Interval.of(Math.min(this.start, other.start), Math.max(this.stop, other.stop));
}
/** Return the interval in common between this and o */
intersection(other) {
return _Interval.of(Math.max(this.start, other.start), Math.min(this.stop, other.stop));
}
/**
* Return the interval with elements from this not in other;
* other must not be totally enclosed (properly contained)
* within this, which would result in two disjoint intervals
* instead of the single one returned by this method.
*/
differenceNotProperlyContained(other) {
let diff = null;
if (other.startsBeforeNonDisjoint(this)) {
diff = _Interval.of(Math.max(this.start, other.stop + 1), this.stop);
} else if (other.startsAfterNonDisjoint(this)) {
diff = _Interval.of(this.start, other.start - 1);
}
return diff;
}
toString() {
return `${this.start}..${this.stop}`;
}
get length() {
if (this.stop < this.start) {
return 0;
}
return this.stop - this.start + 1;
}
};
// src/Vocabulary.ts
var Vocabulary = class _Vocabulary {
static {
__name(this, "Vocabulary");
}
static EMPTY_NAMES = [];
/**
* Gets an empty {@link Vocabulary} instance.
*
*
* No literal or symbol names are assigned to token types, so
* {@link #getDisplayName(int)} returns the numeric value for all tokens
* except {@link Token#EOF}.
*/
static EMPTY_VOCABULARY = new _Vocabulary(_Vocabulary.EMPTY_NAMES, _Vocabulary.EMPTY_NAMES, _Vocabulary.EMPTY_NAMES);
maxTokenType;
literalNames;
symbolicNames;
displayNames;
/**
* Constructs a new instance of {@link Vocabulary} from the specified
* literal, symbolic, and display token names.
*
* @param literalNames The literal names assigned to tokens, or `null`
* if no literal names are assigned.
* @param symbolicNames The symbolic names assigned to tokens, or
* `null` if no symbolic names are assigned.
* @param displayNames The display names assigned to tokens, or `null`
* to use the values in `literalNames` and `symbolicNames` as
* the source of display names, as described in
* {@link #getDisplayName(int)}.
*/
constructor(literalNames, symbolicNames, displayNames) {
this.literalNames = literalNames ?? _Vocabulary.EMPTY_NAMES;
this.symbolicNames = symbolicNames ?? _Vocabulary.EMPTY_NAMES;
this.displayNames = displayNames ?? _Vocabulary.EMPTY_NAMES;
this.maxTokenType = Math.max(this.displayNames.length, Math.max(
this.literalNames.length,
this.symbolicNames.length
)) - 1;
}
/**
* Returns a {@link Vocabulary} instance from the specified set of token
* names. This method acts as a compatibility layer for the single
* `tokenNames` array generated by previous releases of ANTLR.
*
* The resulting vocabulary instance returns `null` for
* {@link getLiteralName getLiteralName(int)} and {@link getSymbolicName getSymbolicName(int)}, and the
* value from `tokenNames` for the display names.
*
* @param tokenNames The token names, or `null` if no token names are
* available.
* @returns A {@link Vocabulary} instance which uses `tokenNames` for
* the display names of tokens.
*/
static fromTokenNames(tokenNames) {
if (tokenNames == null || tokenNames.length === 0) {
return _Vocabulary.EMPTY_VOCABULARY;
}
const literalNames = [...tokenNames];
const symbolicNames = [...tokenNames];
for (let i = 0; i < tokenNames.length; i++) {
const tokenName = tokenNames[i];
if (tokenName == null) {
continue;
}
if (tokenName.length > 0) {
const firstChar = tokenName.codePointAt(0);
if (firstChar === 39) {
symbolicNames[i] = null;
continue;
} else if (firstChar >= 65 && firstChar <= 90) {
literalNames[i] = null;
continue;
}
}
literalNames[i] = null;
symbolicNames[i] = null;
}
return new _Vocabulary(literalNames, symbolicNames, tokenNames);
}
getMaxTokenType() {
return this.maxTokenType;
}
getLiteralName(tokenType) {
if (tokenType >= 0 && tokenType < this.literalNames.length) {
return this.literalNames[tokenType];
}
return null;
}
getSymbolicName(tokenType) {
if (tokenType >= 0 && tokenType < this.symbolicNames.length) {
return this.symbolicNames[tokenType];
}
if (tokenType === Token.EOF) {
return "EOF";
}
return null;
}
getDisplayName(tokenType) {
if (tokenType >= 0 && tokenType < this.displayNames.length) {
const displayName = this.displayNames[tokenType];
if (displayName != null) {
return displayName;
}
}
const literalName = this.getLiteralName(tokenType);
if (literalName != null) {
return literalName;
}
const symbolicName = this.getSymbolicName(tokenType);
if (symbolicName != null) {
return symbolicName;
}
return `${tokenType}`;
}
getLiteralNames() {
return this.literalNames;
}
getSymbolicNames() {
return this.symbolicNames;
}
getDisplayNames() {
return this.displayNames;
}
};
// src/misc/IntervalSet.ts
var IntervalSet = class _IntervalSet {
static {
__name(this, "IntervalSet");
}
/** The list of sorted, disjoint intervals. */
intervals = [];
cachedHashCode;
constructor(set) {
if (set) {
if (Array.isArray(set)) {
for (const el of set) {
this.addOne(el);
}
} else {
this.addSet(set);
}
}
}
/** Create a set with all ints within range [a..b] (inclusive) */
static of(a, b) {
const s = new _IntervalSet();
s.addRange(a, b);
return s;
}
/** Combine all sets in the array and return the union of them */
static or(sets) {
const result = new _IntervalSet();
for (const set of sets) {
result.addSet(set);
}
return result;
}
[Symbol.iterator]() {
return this.intervals[Symbol.iterator]();
}
get(index) {
return this.intervals[index];
}
/**
* Returns the minimum value contained in the set if not isNil().
*
* @returns the minimum value contained in the set.
*/
get minElement() {
if (this.intervals.length === 0) {
return Token.INVALID_TYPE;
}
return this.intervals[0].start;
}
/**
* Returns the maximum value contained in the set if not isNil().
*
* @returns the maximum value contained in the set.
*/
get maxElement() {
if (this.intervals.length === 0) {
return Token.INVALID_TYPE;
}
return this.intervals[this.intervals.length - 1].stop;
}
clear() {
this.cachedHashCode = void 0;
this.intervals = [];
}
/**
* Add a single element to the set. An isolated element is stored
* as a range el..el.
*/
addOne(v) {
this.addInterval(new Interval(v, v));
}
/**
* Add interval; i.e., add all integers from a to b to set.
* If b < a, do nothing.
* Keep list in sorted order (by left range value).
* If overlap, combine ranges. For example,
* If this is {1..5, 10..20}, adding 6..7 yields
* {1..5, 6..7, 10..20}. Adding 4..8 yields {1..8, 10..20}.
*/
addRange(l, h) {
this.addInterval(new Interval(l, h));
}
addInterval(addition) {
this.cachedHashCode = void 0;
if (this.intervals.length === 0) {
this.intervals.push(addition);
} else {
for (let pos = 0; pos < this.intervals.length; pos++) {
const existing = this.intervals[pos];
if (addition.equals(existing)) {
return;
}
if (addition.adjacent(existing) || !addition.disjoint(existing)) {
const bigger = addition.union(existing);
this.intervals[pos] = bigger;
for (let sub = pos + 1; sub < this.intervals.length; ) {
const next = this.intervals[sub];
if (!bigger.adjacent(next) && bigger.disjoint(next)) {
break;
}
this.intervals.splice(sub, 1);
this.intervals[pos] = bigger.union(next);
}
return;
}
if (addition.startsBeforeDisjoint(existing)) {
this.intervals.splice(pos, 0, addition);
return;
}
}
this.intervals.push(addition);
}
}
addSet(other) {
other.intervals.forEach((toAdd) => {
return this.addInterval(toAdd);
}, this);
return this;
}
complementWithVocabulary(vocabulary) {
const result = new _IntervalSet();
if (!vocabulary) {
return result;
}
if (vocabulary.length === 0) {
return result;
}
result.addSet(vocabulary);
return result.subtract(this);
}
complement(minElement, maxElement) {
const result = new _IntervalSet();
result.addInterval(new Interval(minElement, maxElement));
return result.subtract(this);
}
/** combine all sets in the array returned the or'd value */
or(sets) {
const result = new _IntervalSet();
result.addSet(this);
sets.forEach((set) => {
return result.addSet(set);
});
return result;
}
and(other) {
if (other.length === 0) {
return new _IntervalSet();
}
const myIntervals = this.intervals;
const theirIntervals = other.intervals;
let intersection;
const mySize = myIntervals.length;
const theirSize = theirIntervals.length;
let i = 0;
let j = 0;
while (i < mySize && j < theirSize) {
const mine = myIntervals[i];
const theirs = theirIntervals[j];
if (mine.startsBeforeDisjoint(theirs)) {
i++;
} else if (theirs.startsBeforeDisjoint(mine)) {
j++;
} else if (mine.properlyContains(theirs)) {
if (!intersection) {
intersection = new _IntervalSet();
}
intersection.addInterval(mine.intersection(theirs));
j++;
} else if (theirs.properlyContains(mine)) {
if (!intersection) {
intersection = new _IntervalSet();
}
intersection.addInterval(mine.intersection(theirs));
i++;
} else if (!mine.disjoint(theirs)) {
if (!intersection) {
intersection = new _IntervalSet();
}
intersection.addInterval(mine.intersection(theirs));
if (mine.startsAfterNonDisjoint(theirs)) {
j++;
} else if (theirs.startsAfterNonDisjoint(mine)) {
i++;
}
}
}
if (!intersection) {
return new _IntervalSet();
}
return intersection;
}
/**
* Compute the set difference between two interval sets. The specific
* operation is `left - right`. If either of the input sets is
* `null`, it is treated as though it was an empty set.
*/
subtract(other) {
if (this.length === 0) {
return new _IntervalSet();
}
const result = new _IntervalSet(this);
if (other.length === 0) {
return result;
}
let resultI = 0;
let rightI = 0;
while (resultI < result.intervals.length && rightI < other.intervals.length) {
const resultInterval = result.intervals[resultI];
const rightInterval = other.intervals[rightI];
if (rightInterval.stop < resultInterval.start) {
rightI++;
continue;
}
if (rightInterval.start > resultInterval.stop) {
resultI++;
continue;
}
let beforeCurrent;
let afterCurrent;
if (rightInterval.start > resultInterval.start) {
beforeCurrent = new Interval(resultInterval.start, rightInterval.start - 1);
}
if (rightInterval.stop < resultInterval.stop) {
afterCurrent = new Interval(rightInterval.stop + 1, resultInterval.stop);
}
if (beforeCurrent) {
if (afterCurrent) {
result.intervals[resultI] = beforeCurrent;
result.intervals.splice(resultI + 1, 0, afterCurrent);
resultI++;
rightI++;
} else {
result.intervals[resultI] = beforeCurrent;
resultI++;
}
} else {
if (afterCurrent) {
result.intervals[resultI] = afterCurrent;
rightI++;
} else {
result.intervals.splice(resultI, 1);
}
}
}
return result;
}
contains(el) {
const n2 = this.intervals.length;
let l = 0;
let r = n2 - 1;
while (l <= r) {
const m2 = Math.floor((l + r) / 2);
const interval = this.intervals[m2];
if (interval.stop < el) {
l = m2 + 1;
} else if (interval.start > el) {
r = m2 - 1;
} else {
return true;
}
}
return false;
}
removeRange(toRemove) {
this.cachedHashCode = void 0;
if (toRemove.start === toRemove.stop) {
this.removeOne(toRemove.start);
} else if (this.intervals !== null) {
let pos = 0;
for (const existing of this.intervals) {
if (toRemove.stop <= existing.start) {
return;
} else if (toRemove.start > existing.start && toRemove.stop < existing.stop) {
this.intervals[pos] = new Interval(existing.start, toRemove.start);
const x = new Interval(toRemove.stop, existing.stop);
this.intervals.splice(pos, 0, x);
return;
} else if (toRemove.start <= existing.start && toRemove.stop >= existing.stop) {
this.intervals.splice(pos, 1);
pos = pos - 1;
} else if (toRemove.start < existing.stop) {
this.intervals[pos] = new Interval(existing.start, toRemove.start);
} else if (toRemove.stop < existing.stop) {
this.intervals[pos] = new Interval(toRemove.stop, existing.stop);
}
pos += 1;
}
}
}
removeOne(value) {
this.cachedHashCode = void 0;
for (let i = 0; i < this.intervals.length; i++) {
const existing = this.intervals[i];
if (value < existing.start) {
return;
} else if (value === existing.start && value === existing.stop) {
this.intervals.splice(i, 1);
return;
} else if (value === existing.start) {
this.intervals[i] = new Interval(existing.start + 1, existing.stop);
return;
} else if (value === existing.stop) {
this.intervals[i] = new Interval(existing.start, existing.stop - 1);
return;
} else if (value < existing.stop) {
const replace = new Interval(existing.start, value - 1);
this.intervals[i] = new Interval(value + 1, existing.stop);
this.intervals.splice(i, 0, replace);
return;
}
}
}
hashCode() {
if (this.cachedHashCode === void 0) {
let hash = MurmurHash.initialize();
for (const interval of this.intervals) {
hash = MurmurHash.update(hash, interval.start);
hash = MurmurHash.update(hash, interval.stop);
}
this.cachedHashCode = MurmurHash.finish(hash, this.intervals.length * 2);
}
return this.cachedHashCode;
}
/**
* Are two IntervalSets equal? Because all intervals are sorted and disjoint, equals is a simple linear walk over
* both lists to make sure they are the same. Interval.equals() is used by the List.equals() method to check
* the ranges.
*/
equals(other) {
if (this === other) {
return true;
}
if (this.intervals.length !== other.intervals.length) {
return false;
}
for (let i = 0; i < this.intervals.length; i++) {
if (!this.intervals[i].equals(other.intervals[i])) {
return false;
}
}
return true;
}
toString(elementsAreChar) {
if (this.intervals.length === 0) {
return "{}";
}
let result = "";
if (this.length > 1) {
result += "{";
}
for (let i = 0; i < this.intervals.length; ++i) {
const interval = this.intervals[i];
const start = interval.start;
const stop = interval.stop;
if (start === stop) {
if (start === Token.EOF) {
result += "<EOF>";
} else if (elementsAreChar) {
result += "'" + String.fromCodePoint(start) + "'";
} else {
result += start;
}
} else {
if (elementsAreChar) {
result += "'" + String.fromCodePoint(start) + "'..'" + String.fromCodePoint(stop) + "'";
} else {
result += start + ".." + stop;
}
}
if (i < this.intervals.length - 1) {
result += ", ";
}
}
if (this.length > 1) {
result += "}";
}
return result;
}
toStringWithVocabulary(vocabulary) {
if (this.intervals.length === 0) {
return "{}";
}
let result = "";
if (this.length > 1) {
result += "{";
}
for (let i = 0; i < this.intervals.length; ++i) {
const interval = this.intervals[i];
const start = interval.start;
const stop = interval.stop;
if (start === stop) {
if (start === Token.EOF) {
result += "<EOF>";
} else {
result += this.elementName(vocabulary, start);
}
} else {
for (let i2 = start; i2 <= stop; ++i2) {
if (i2 > start) {
result += ", ";
}
result += this.elementName(vocabulary, i2);
}
}
if (i < this.intervals.length - 1) {
result += ", ";
}
}
if (this.length > 1) {
result += "}";
}
return result;
}
toStringWithRuleNames(ruleNames) {
if (this.intervals.length === 0) {
return "{}";
}
let result = "";
if (this.length > 1) {
result += "{";
}
const vocabulary = Vocabulary.fromTokenNames(ruleNames);
for (let i = 0; i < this.intervals.length; ++i) {
const interval = this.intervals[i];
const start = interval.start;
const stop = interval.stop;
if (start === stop) {
if (start === Token.EOF) {
result += "<EOF>";
} else {
result += this.elementName(vocabulary, start);
}
} else {
for (let i2 = start; i2 <= stop; ++i2) {
if (i2 > start) {
result += ", ";
}
result += this.elementName(vocabulary, i2);
}
}
if (i < this.intervals.length - 1) {
result += ", ";
}
}
if (this.length > 1) {
result += "}";
}
return result;
}
toArray() {
const data = [];
for (const interval of this.intervals) {
for (let j = interval.start; j <= interval.stop; j++) {
data.push(j);
}
}
return data;
}
/** @returns the number of elements in this set. */
get length() {
let result = 0;
for (const interval of this.intervals) {
result += interval.length;
}
return result;
}
elementName(vocabulary, token) {
if (token === Token.EOF) {
return "<EOF>";
}
if (token === Token.EPSILON) {
return "<EPSILON>";
}
return vocabulary.getDisplayName(token);
}
};
// src/utils/helpers.ts
var isComparable = /* @__PURE__ */ __name((candidate) => {
return typeof candidate.equals === "function";
}, "isComparable");
var valueToString = /* @__PURE__ */ __name((v) => {
return v === null ? "null" : v;
}, "valueToString");
var arrayToString = /* @__PURE__ */ __name((value) => {
return Array.isArray(value) ? "[" + value.map(valueToString).join(", ") + "]" : "null";
}, "arrayToString");
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");
var equalNumberArrays = /* @__PURE__ */ __name((a, b) => {
if (a === b) {
return true;
}
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}, "equalNumberArrays");
var escapeWhitespace = /* @__PURE__ */ __name((s, escapeSpaces = false) => {
s = s.replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
if (escapeSpaces) {
s = s.replace(/ /g, "\xB7");
}
return s;
}, "escapeWhitespace");
// 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.to