UNPKG

antlr4ng

Version:

Alternative JavaScript/TypeScript runtime for ANTLR4

560 lines (547 loc) 17.1 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/dfa/DFA.ts var DFA_exports = {}; __export(DFA_exports, { DFA: () => DFA }); module.exports = __toCommonJS(DFA_exports); // src/dfa/DFASerializer.ts var DFASerializer = class { static { __name(this, "DFASerializer"); } dfa; vocabulary; constructor(dfa, vocabulary) { this.dfa = dfa; this.vocabulary = vocabulary; } toString() { if (!this.dfa.s0) { return ""; } let buf = ""; const states = this.dfa.getStates(); for (const s of states) { let n = 0; n = s.edges.length; for (let i = 0; i < n; i++) { const t = s.edges[i]; if (t && t.stateNumber !== 2147483647) { buf += this.getStateString(s); const label = this.getEdgeLabel(i); buf += "-"; buf += label; buf += "->"; buf += this.getStateString(t); buf += "\n"; } } } return buf; } getEdgeLabel(i) { const name = this.vocabulary.getDisplayName(i - 1); return `${name}`; } getStateString(s) { const n = s.stateNumber; const baseStateStr = (s.isAcceptState ? ":" : "") + "s" + n + (s.requiresFullContext ? "^" : ""); if (s.isAcceptState) { if (s.predicates !== null) { return `${baseStateStr}=>${s.predicates.toString()}`; } return `${baseStateStr}=>${s.prediction}`; } else { return `${baseStateStr}`; } } }; // src/utils/helpers.ts 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"); // src/dfa/DFAState.ts var DFAState = class _DFAState { static { __name(this, "DFAState"); } stateNumber = -1; configs; /** * `edges[symbol]` points to target of symbol. Shift up by 1 so (-1) {@link Token.EOF} maps to `edges[0]`. */ edges = []; isAcceptState = false; /** * If accept state, what ttype do we match or alt do we predict? This is set to {@link ATN.INVALID_ALT_NUMBER} * when {@link predicates} `!= null` or {@link requiresFullContext}. */ prediction = -1; lexerActionExecutor = null; /** * Indicates that this state was created during SLL prediction that discovered a conflict between the configurations * in the state. Future {@link ParserATNSimulator.execATN} invocations immediately jumped doing * full context prediction if this field is true. */ requiresFullContext = false; /** * During SLL parsing, this is a list of predicates associated with the ATN configurations of the DFA state. * When we have predicates, {@link requiresFullContext} is `false` since full context prediction evaluates * predicates on-the-fly. If this is not null, then {@link prediction} is `ATN.INVALID_ALT_NUMBER`. * * We only use these for non-{@link #requiresFullContext} but conflicting states. That * means we know from the context (it's $ or we don't dip into outer * context) that it's an ambiguity not a conflict. * * This list is computed by {@link ParserATNSimulator#predicateDFAState}. */ predicates = null; constructor(configs) { if (configs) { this.configs = configs; } } static fromState(stateNumber) { const result = new _DFAState(); result.stateNumber = stateNumber; return result; } static fromConfigs(configs) { return new _DFAState(configs); } static hashCode(state) { return state.configs.hashCode(); } /** * Two {@link DFAState} instances are equal if their ATN configuration sets * are the same. This method is used to see if a state already exists. * * Because the number of alternatives and number of ATN configurations are * finite, there is a finite number of DFA states that can be processed. * This is necessary to show that the algorithm terminates. * * Cannot test the DFA state numbers here because in * {@link ParserATNSimulator#addDFAState} we need to know if any other state * exists that has this exact set of ATN configurations. The * {@link #stateNumber} is irrelevant. * * @param a The first {@link DFAState}. * @param b The second {@link DFAState}. * * @returns `true` if the two states are equal, otherwise `false`. */ static equals(a, b) { return a.configs.equals(b.configs); } /** * @returns the set of all alts mentioned by all ATN configurations in this DFA state. */ getAltSet() { const alts = /* @__PURE__ */ new Set(); for (const config of this.configs) { alts.add(config.alt); } if (alts.size === 0) { return null; } return alts; } toString() { let buf = ""; buf += this.stateNumber; buf += ":"; buf += this.configs ? this.configs.toString() : ""; if (this.isAcceptState) { buf += "=>"; if (this.predicates) { buf += arrayToString(this.predicates); } else { buf += this.prediction; } } return buf.toString(); } }; // 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 = {})); // 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/dfa/LexerDFASerializer.ts var LexerDFASerializer = class extends DFASerializer { static { __name(this, "LexerDFASerializer"); } constructor(dfa) { super(dfa, Vocabulary.EMPTY_VOCABULARY); } getEdgeLabel = /* @__PURE__ */ __name((i) => { return "'" + String.fromCharCode(i) + "'"; }, "getEdgeLabel"); }; // src/atn/ATNState.ts var ATNState = class _ATNState { static { __name(this, "ATNState"); } static INVALID_STATE_NUMBER = -1; static INVALID_TYPE = 0; static BASIC = 1; static RULE_START = 2; static BLOCK_START = 3; static PLUS_BLOCK_START = 4; static STAR_BLOCK_START = 5; static TOKEN_START = 6; static RULE_STOP = 7; static BLOCK_END = 8; static STAR_LOOP_BACK = 9; static STAR_LOOP_ENTRY = 10; static PLUS_LOOP_BACK = 11; static LOOP_END = 12; static stateType = _ATNState.INVALID_STATE_NUMBER; stateNumber = 0; ruleIndex = 0; // at runtime, we don't have Rule objects epsilonOnlyTransitions = false; /** Used to cache lookahead during parsing, not used during construction */ nextTokenWithinRule; /** Track the transitions emanating from this ATN state. */ transitions = []; hashCode() { return this.stateNumber; } equals(other) { return this.stateNumber === other.stateNumber; } toString() { return `${this.stateNumber}`; } addTransitionAtIndex(index, transition) { if (this.transitions.length === 0) { this.epsilonOnlyTransitions = transition.isEpsilon; } else if (this.epsilonOnlyTransitions !== transition.isEpsilon) { this.epsilonOnlyTransitions = false; } this.transitions.splice(index, 1, transition); } addTransition(transition) { if (this.transitions.length === 0) { this.epsilonOnlyTransitions = transition.isEpsilon; } else if (this.epsilonOnlyTransitions !== transition.isEpsilon) { this.epsilonOnlyTransitions = false; } this.transitions.push(transition); } setTransition(i, e) { this.transitions.splice(i, 1, e); } removeTransition(index) { const t = this.transitions.splice(index, 1); return t[0]; } }; // src/atn/DecisionState.ts var DecisionState = class extends ATNState { static { __name(this, "DecisionState"); } decision = -1; nonGreedy = false; }; // src/atn/StarLoopEntryState.ts var StarLoopEntryState = class extends DecisionState { static { __name(this, "StarLoopEntryState"); } static stateType = ATNState.STAR_LOOP_ENTRY; // This is always set during ATN deserialization loopBackState; /** * Indicates whether this state can benefit from a precedence DFA during SLL * decision making. * * This is a computed property that is calculated during ATN deserialization * and stored for use in {@link ParserATNSimulator} and * {@link ParserInterpreter}. * * @see `DFA.isPrecedenceDfa` */ precedenceRuleDecision = false; }; // src/dfa/DFA.ts var DFA = class { static { __name(this, "DFA"); } s0; decision; /** From which ATN state did we create this DFA? */ atnStartState; /** * Gets whether this DFA is a precedence DFA. Precedence DFAs use a special * start state {@link #s0} which is not stored in {@link #states}. The * {@link DFAState#edges} array for this start state contains outgoing edges * supplying individual start states corresponding to specific precedence * values. * * @returns `true` if this is a precedence DFA; otherwise, `false`. */ isPrecedenceDfa; /** * A mapping from an ATNConfigSet hash to a DFAState. * Used to quick look up the DFA state for a particular configuration set. */ states = /* @__PURE__ */ new Map(); constructor(atnStartState, decision) { this.atnStartState = atnStartState; this.decision = decision ?? 0; let precedenceDfa = false; if (atnStartState instanceof StarLoopEntryState) { if (atnStartState.precedenceRuleDecision) { precedenceDfa = true; this.s0 = DFAState.fromState(-1); } } this.isPrecedenceDfa = precedenceDfa; } [Symbol.iterator] = () => { return this.states.values()[Symbol.iterator](); }; /** * Get the start state for a specific precedence value. * * @param precedence The current precedence. @returns The start state corresponding to the specified precedence, or * `null` if no start state exists for the specified precedence. * * @throws IllegalStateException if this is not a precedence DFA. * @see #isPrecedenceDfa */ getPrecedenceStartState = /* @__PURE__ */ __name((precedence) => { if (!this.isPrecedenceDfa) { throw new Error(`Only precedence DFAs may contain a precedence start state.`); } if (!this.s0 || !this.s0.edges || precedence < 0 || precedence >= this.s0.edges.length) { return void 0; } return this.s0.edges[precedence]; }, "getPrecedenceStartState"); /** * Set the start state for a specific precedence value. * * @param precedence The current precedence. * @param startState The start state corresponding to the specified precedence. */ setPrecedenceStartState = /* @__PURE__ */ __name((precedence, startState) => { if (!this.isPrecedenceDfa) { throw new Error(`Only precedence DFAs may contain a precedence start state.`); } if (precedence < 0 || !this.s0) { return; } this.s0.edges[precedence] = startState; }, "setPrecedenceStartState"); /** * @returns a list of all states in this DFA, ordered by state number. */ getStates() { const result = [...this.states.values()]; result.sort((o1, o2) => { return o1.stateNumber - o2.stateNumber; }); return result; } getState(state) { return this.states.get(state.configs.hashCode()) ?? null; } getStateForConfigs(configs) { return this.states.get(configs.hashCode()) ?? null; } addState(state) { const hash = state.configs.hashCode(); if (this.states.has(hash)) { return; } this.states.set(hash, state); state.stateNumber = this.states.size - 1; } toString(vocabulary) { if (!vocabulary) { return this.toString(Vocabulary.EMPTY_VOCABULARY); } if (!this.s0) { return ""; } const serializer = new DFASerializer(this, vocabulary); return serializer.toString() ?? ""; } toLexerString() { if (!this.s0) { return ""; } const serializer = new LexerDFASerializer(this); return serializer.toString() ?? ""; } get length() { return this.states.size; } };