UNPKG

32.2 kBJavaScriptView Raw
1"use strict";
2/*!
3 * Copyright 2016 The ANTLR Project. All rights reserved.
4 * Licensed under the BSD-3-Clause license. See LICENSE file in the project root for license information.
5 */
6var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
7 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
8 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
9 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;
10 return c > 3 && r && Object.defineProperty(target, key, r), r;
11};
12var __param = (this && this.__param) || function (paramIndex, decorator) {
13 return function (target, key) { decorator(target, key, paramIndex); }
14};
15var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
16 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
17 return new (P || (P = Promise))(function (resolve, reject) {
18 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
19 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
20 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
21 step((generator = generator.apply(thisArg, _arguments || [])).next());
22 });
23};
24Object.defineProperty(exports, "__esModule", { value: true });
25exports.Parser = void 0;
26const Utils = require("./misc/Utils");
27const ATNDeserializationOptions_1 = require("./atn/ATNDeserializationOptions");
28const ATNDeserializer_1 = require("./atn/ATNDeserializer");
29const DefaultErrorStrategy_1 = require("./DefaultErrorStrategy");
30const ErrorNode_1 = require("./tree/ErrorNode");
31const IntegerStack_1 = require("./misc/IntegerStack");
32const Lexer_1 = require("./Lexer");
33const Decorators_1 = require("./Decorators");
34const ParseInfo_1 = require("./atn/ParseInfo");
35const ParserATNSimulator_1 = require("./atn/ParserATNSimulator");
36const ProxyParserErrorListener_1 = require("./ProxyParserErrorListener");
37const Recognizer_1 = require("./Recognizer");
38const TerminalNode_1 = require("./tree/TerminalNode");
39const Token_1 = require("./Token");
40class TraceListener {
41 constructor(ruleNames, tokenStream) {
42 this.ruleNames = ruleNames;
43 this.tokenStream = tokenStream;
44 }
45 enterEveryRule(ctx) {
46 console.log("enter " + this.ruleNames[ctx.ruleIndex] +
47 ", LT(1)=" + this.tokenStream.LT(1).text);
48 }
49 exitEveryRule(ctx) {
50 console.log("exit " + this.ruleNames[ctx.ruleIndex] +
51 ", LT(1)=" + this.tokenStream.LT(1).text);
52 }
53 visitErrorNode(node) {
54 // intentionally empty
55 }
56 visitTerminal(node) {
57 let parent = node.parent.ruleContext;
58 let token = node.symbol;
59 console.log("consume " + token + " rule " + this.ruleNames[parent.ruleIndex]);
60 }
61}
62__decorate([
63 Decorators_1.Override
64], TraceListener.prototype, "enterEveryRule", null);
65__decorate([
66 Decorators_1.Override
67], TraceListener.prototype, "exitEveryRule", null);
68__decorate([
69 Decorators_1.Override
70], TraceListener.prototype, "visitErrorNode", null);
71__decorate([
72 Decorators_1.Override
73], TraceListener.prototype, "visitTerminal", null);
74/** This is all the parsing support code essentially; most of it is error recovery stuff. */
75class Parser extends Recognizer_1.Recognizer {
76 constructor(input) {
77 super();
78 /**
79 * The error handling strategy for the parser. The default value is a new
80 * instance of {@link DefaultErrorStrategy}.
81 *
82 * @see #getErrorHandler
83 * @see #setErrorHandler
84 */
85 this._errHandler = new DefaultErrorStrategy_1.DefaultErrorStrategy();
86 this._precedenceStack = new IntegerStack_1.IntegerStack();
87 /**
88 * Specifies whether or not the parser should construct a parse tree during
89 * the parsing process. The default value is `true`.
90 *
91 * @see `buildParseTree`
92 */
93 this._buildParseTrees = true;
94 /**
95 * The list of {@link ParseTreeListener} listeners registered to receive
96 * events during the parse.
97 *
98 * @see #addParseListener
99 */
100 this._parseListeners = [];
101 /**
102 * The number of syntax errors reported during parsing. This value is
103 * incremented each time {@link #notifyErrorListeners} is called.
104 */
105 this._syntaxErrors = 0;
106 /** Indicates parser has match()ed EOF token. See {@link #exitRule()}. */
107 this.matchedEOF = false;
108 this._precedenceStack.push(0);
109 this.inputStream = input;
110 }
111 reset(resetInput) {
112 // Note: this method executes when not parsing, so _ctx can be undefined
113 if (resetInput === undefined || resetInput) {
114 this.inputStream.seek(0);
115 }
116 this._errHandler.reset(this);
117 this._ctx = undefined;
118 this._syntaxErrors = 0;
119 this.matchedEOF = false;
120 this.isTrace = false;
121 this._precedenceStack.clear();
122 this._precedenceStack.push(0);
123 let interpreter = this.interpreter;
124 if (interpreter != null) {
125 interpreter.reset();
126 }
127 }
128 /**
129 * Match current input symbol against `ttype`. If the symbol type
130 * matches, {@link ANTLRErrorStrategy#reportMatch} and {@link #consume} are
131 * called to complete the match process.
132 *
133 * If the symbol type does not match,
134 * {@link ANTLRErrorStrategy#recoverInline} is called on the current error
135 * strategy to attempt recovery. If {@link #getBuildParseTree} is
136 * `true` and the token index of the symbol returned by
137 * {@link ANTLRErrorStrategy#recoverInline} is -1, the symbol is added to
138 * the parse tree by calling {@link #createErrorNode(ParserRuleContext, Token)} then
139 * {@link ParserRuleContext#addErrorNode(ErrorNode)}.
140 *
141 * @param ttype the token type to match
142 * @returns the matched symbol
143 * @ if the current input symbol did not match
144 * `ttype` and the error strategy could not recover from the
145 * mismatched symbol
146 */
147 match(ttype) {
148 let t = this.currentToken;
149 if (t.type === ttype) {
150 if (ttype === Token_1.Token.EOF) {
151 this.matchedEOF = true;
152 }
153 this._errHandler.reportMatch(this);
154 this.consume();
155 }
156 else {
157 t = this._errHandler.recoverInline(this);
158 if (this._buildParseTrees && t.tokenIndex === -1) {
159 // we must have conjured up a new token during single token insertion
160 // if it's not the current symbol
161 this._ctx.addErrorNode(this.createErrorNode(this._ctx, t));
162 }
163 }
164 return t;
165 }
166 /**
167 * Match current input symbol as a wildcard. If the symbol type matches
168 * (i.e. has a value greater than 0), {@link ANTLRErrorStrategy#reportMatch}
169 * and {@link #consume} are called to complete the match process.
170 *
171 * If the symbol type does not match,
172 * {@link ANTLRErrorStrategy#recoverInline} is called on the current error
173 * strategy to attempt recovery. If {@link #getBuildParseTree} is
174 * `true` and the token index of the symbol returned by
175 * {@link ANTLRErrorStrategy#recoverInline} is -1, the symbol is added to
176 * the parse tree by calling {@link Parser#createErrorNode(ParserRuleContext, Token)} then
177 * {@link ParserRuleContext#addErrorNode(ErrorNode)}.
178 *
179 * @returns the matched symbol
180 * @ if the current input symbol did not match
181 * a wildcard and the error strategy could not recover from the mismatched
182 * symbol
183 */
184 matchWildcard() {
185 let t = this.currentToken;
186 if (t.type > 0) {
187 this._errHandler.reportMatch(this);
188 this.consume();
189 }
190 else {
191 t = this._errHandler.recoverInline(this);
192 if (this._buildParseTrees && t.tokenIndex === -1) {
193 // we must have conjured up a new token during single token insertion
194 // if it's not the current symbol
195 this._ctx.addErrorNode(this.createErrorNode(this._ctx, t));
196 }
197 }
198 return t;
199 }
200 /**
201 * Track the {@link ParserRuleContext} objects during the parse and hook
202 * them up using the {@link ParserRuleContext#children} list so that it
203 * forms a parse tree. The {@link ParserRuleContext} returned from the start
204 * rule represents the root of the parse tree.
205 *
206 * Note that if we are not building parse trees, rule contexts only point
207 * upwards. When a rule exits, it returns the context but that gets garbage
208 * collected if nobody holds a reference. It points upwards but nobody
209 * points at it.
210 *
211 * When we build parse trees, we are adding all of these contexts to
212 * {@link ParserRuleContext#children} list. Contexts are then not candidates
213 * for garbage collection.
214 */
215 set buildParseTree(buildParseTrees) {
216 this._buildParseTrees = buildParseTrees;
217 }
218 /**
219 * Gets whether or not a complete parse tree will be constructed while
220 * parsing. This property is `true` for a newly constructed parser.
221 *
222 * @returns `true` if a complete parse tree will be constructed while
223 * parsing, otherwise `false`
224 */
225 get buildParseTree() {
226 return this._buildParseTrees;
227 }
228 getParseListeners() {
229 return this._parseListeners;
230 }
231 /**
232 * Registers `listener` to receive events during the parsing process.
233 *
234 * To support output-preserving grammar transformations (including but not
235 * limited to left-recursion removal, automated left-factoring, and
236 * optimized code generation), calls to listener methods during the parse
237 * may differ substantially from calls made by
238 * {@link ParseTreeWalker#DEFAULT} used after the parse is complete. In
239 * particular, rule entry and exit events may occur in a different order
240 * during the parse than after the parser. In addition, calls to certain
241 * rule entry methods may be omitted.
242 *
243 * With the following specific exceptions, calls to listener events are
244 * *deterministic*, i.e. for identical input the calls to listener
245 * methods will be the same.
246 *
247 * * Alterations to the grammar used to generate code may change the
248 * behavior of the listener calls.
249 * * Alterations to the command line options passed to ANTLR 4 when
250 * generating the parser may change the behavior of the listener calls.
251 * * Changing the version of the ANTLR Tool used to generate the parser
252 * may change the behavior of the listener calls.
253 *
254 * @param listener the listener to add
255 *
256 * @throws {@link TypeError} if `listener` is `undefined`
257 */
258 addParseListener(listener) {
259 if (listener == null) {
260 throw new TypeError("listener cannot be null");
261 }
262 this._parseListeners.push(listener);
263 }
264 /**
265 * Remove `listener` from the list of parse listeners.
266 *
267 * If `listener` is `undefined` or has not been added as a parse
268 * listener, this method does nothing.
269 *
270 * @see #addParseListener
271 *
272 * @param listener the listener to remove
273 */
274 removeParseListener(listener) {
275 let index = this._parseListeners.findIndex((l) => l === listener);
276 if (index !== -1) {
277 this._parseListeners.splice(index, 1);
278 }
279 }
280 /**
281 * Remove all parse listeners.
282 *
283 * @see #addParseListener
284 */
285 removeParseListeners() {
286 this._parseListeners.length = 0;
287 }
288 /**
289 * Notify any parse listeners of an enter rule event.
290 *
291 * @see #addParseListener
292 */
293 triggerEnterRuleEvent() {
294 for (let listener of this._parseListeners) {
295 if (listener.enterEveryRule) {
296 listener.enterEveryRule(this._ctx);
297 }
298 this._ctx.enterRule(listener);
299 }
300 }
301 /**
302 * Notify any parse listeners of an exit rule event.
303 *
304 * @see #addParseListener
305 */
306 triggerExitRuleEvent() {
307 // reverse order walk of listeners
308 for (let i = this._parseListeners.length - 1; i >= 0; i--) {
309 let listener = this._parseListeners[i];
310 this._ctx.exitRule(listener);
311 if (listener.exitEveryRule) {
312 listener.exitEveryRule(this._ctx);
313 }
314 }
315 }
316 /**
317 * Gets the number of syntax errors reported during parsing. This value is
318 * incremented each time {@link #notifyErrorListeners} is called.
319 *
320 * @see #notifyErrorListeners
321 */
322 get numberOfSyntaxErrors() {
323 return this._syntaxErrors;
324 }
325 get tokenFactory() {
326 return this._input.tokenSource.tokenFactory;
327 }
328 /**
329 * The ATN with bypass alternatives is expensive to create so we create it
330 * lazily.
331 *
332 * @ if the current parser does not
333 * implement the `serializedATN` property.
334 */
335 getATNWithBypassAlts() {
336 let serializedAtn = this.serializedATN;
337 if (serializedAtn == null) {
338 throw new Error("The current parser does not support an ATN with bypass alternatives.");
339 }
340 let result = Parser.bypassAltsAtnCache.get(serializedAtn);
341 if (result == null) {
342 let deserializationOptions = new ATNDeserializationOptions_1.ATNDeserializationOptions();
343 deserializationOptions.isGenerateRuleBypassTransitions = true;
344 result = new ATNDeserializer_1.ATNDeserializer(deserializationOptions).deserialize(Utils.toCharArray(serializedAtn));
345 Parser.bypassAltsAtnCache.set(serializedAtn, result);
346 }
347 return result;
348 }
349 compileParseTreePattern(pattern, patternRuleIndex, lexer) {
350 return __awaiter(this, void 0, void 0, function* () {
351 if (!lexer) {
352 if (this.inputStream) {
353 let tokenSource = this.inputStream.tokenSource;
354 if (tokenSource instanceof Lexer_1.Lexer) {
355 lexer = tokenSource;
356 }
357 }
358 if (!lexer) {
359 throw new Error("Parser can't discover a lexer to use");
360 }
361 }
362 let currentLexer = lexer;
363 let m = yield Promise.resolve().then(() => require("./tree/pattern/ParseTreePatternMatcher"));
364 let matcher = new m.ParseTreePatternMatcher(currentLexer, this);
365 return matcher.compile(pattern, patternRuleIndex);
366 });
367 }
368 get errorHandler() {
369 return this._errHandler;
370 }
371 set errorHandler(handler) {
372 this._errHandler = handler;
373 }
374 get inputStream() {
375 return this._input;
376 }
377 /** Set the token stream and reset the parser. */
378 set inputStream(input) {
379 this.reset(false);
380 this._input = input;
381 }
382 /** Match needs to return the current input symbol, which gets put
383 * into the label for the associated token ref; e.g., x=ID.
384 */
385 get currentToken() {
386 return this._input.LT(1);
387 }
388 notifyErrorListeners(msg, offendingToken, e) {
389 if (offendingToken === undefined) {
390 offendingToken = this.currentToken;
391 }
392 else if (offendingToken === null) {
393 offendingToken = undefined;
394 }
395 this._syntaxErrors++;
396 let line = -1;
397 let charPositionInLine = -1;
398 if (offendingToken != null) {
399 line = offendingToken.line;
400 charPositionInLine = offendingToken.charPositionInLine;
401 }
402 let listener = this.getErrorListenerDispatch();
403 if (listener.syntaxError) {
404 listener.syntaxError(this, offendingToken, line, charPositionInLine, msg, e);
405 }
406 }
407 /**
408 * Consume and return the [current symbol](`currentToken`).
409 *
410 * E.g., given the following input with `A` being the current
411 * lookahead symbol, this function moves the cursor to `B` and returns
412 * `A`.
413 *
414 * ```
415 * A B
416 * ^
417 * ```
418 *
419 * If the parser is not in error recovery mode, the consumed symbol is added
420 * to the parse tree using {@link ParserRuleContext#addChild(TerminalNode)}, and
421 * {@link ParseTreeListener#visitTerminal} is called on any parse listeners.
422 * If the parser *is* in error recovery mode, the consumed symbol is
423 * added to the parse tree using {@link #createErrorNode(ParserRuleContext, Token)} then
424 * {@link ParserRuleContext#addErrorNode(ErrorNode)} and
425 * {@link ParseTreeListener#visitErrorNode} is called on any parse
426 * listeners.
427 */
428 consume() {
429 let o = this.currentToken;
430 if (o.type !== Parser.EOF) {
431 this.inputStream.consume();
432 }
433 let hasListener = this._parseListeners.length !== 0;
434 if (this._buildParseTrees || hasListener) {
435 if (this._errHandler.inErrorRecoveryMode(this)) {
436 let node = this._ctx.addErrorNode(this.createErrorNode(this._ctx, o));
437 if (hasListener) {
438 for (let listener of this._parseListeners) {
439 if (listener.visitErrorNode) {
440 listener.visitErrorNode(node);
441 }
442 }
443 }
444 }
445 else {
446 let node = this.createTerminalNode(this._ctx, o);
447 this._ctx.addChild(node);
448 if (hasListener) {
449 for (let listener of this._parseListeners) {
450 if (listener.visitTerminal) {
451 listener.visitTerminal(node);
452 }
453 }
454 }
455 }
456 }
457 return o;
458 }
459 /**
460 * How to create a token leaf node associated with a parent.
461 * Typically, the terminal node to create is not a function of the parent.
462 *
463 * @since 4.7
464 */
465 createTerminalNode(parent, t) {
466 return new TerminalNode_1.TerminalNode(t);
467 }
468 /**
469 * How to create an error node, given a token, associated with a parent.
470 * Typically, the error node to create is not a function of the parent.
471 *
472 * @since 4.7
473 */
474 createErrorNode(parent, t) {
475 return new ErrorNode_1.ErrorNode(t);
476 }
477 addContextToParseTree() {
478 let parent = this._ctx._parent;
479 // add current context to parent if we have a parent
480 if (parent != null) {
481 parent.addChild(this._ctx);
482 }
483 }
484 /**
485 * Always called by generated parsers upon entry to a rule. Access field
486 * {@link #_ctx} get the current context.
487 */
488 enterRule(localctx, state, ruleIndex) {
489 this.state = state;
490 this._ctx = localctx;
491 this._ctx._start = this._input.LT(1);
492 if (this._buildParseTrees) {
493 this.addContextToParseTree();
494 }
495 this.triggerEnterRuleEvent();
496 }
497 enterLeftFactoredRule(localctx, state, ruleIndex) {
498 this.state = state;
499 if (this._buildParseTrees) {
500 let factoredContext = this._ctx.getChild(this._ctx.childCount - 1);
501 this._ctx.removeLastChild();
502 factoredContext._parent = localctx;
503 localctx.addChild(factoredContext);
504 }
505 this._ctx = localctx;
506 this._ctx._start = this._input.LT(1);
507 if (this._buildParseTrees) {
508 this.addContextToParseTree();
509 }
510 this.triggerEnterRuleEvent();
511 }
512 exitRule() {
513 if (this.matchedEOF) {
514 // if we have matched EOF, it cannot consume past EOF so we use LT(1) here
515 this._ctx._stop = this._input.LT(1); // LT(1) will be end of file
516 }
517 else {
518 this._ctx._stop = this._input.tryLT(-1); // stop node is what we just matched
519 }
520 // trigger event on _ctx, before it reverts to parent
521 this.triggerExitRuleEvent();
522 this.state = this._ctx.invokingState;
523 this._ctx = this._ctx._parent;
524 }
525 enterOuterAlt(localctx, altNum) {
526 localctx.altNumber = altNum;
527 // if we have new localctx, make sure we replace existing ctx
528 // that is previous child of parse tree
529 if (this._buildParseTrees && this._ctx !== localctx) {
530 let parent = this._ctx._parent;
531 if (parent != null) {
532 parent.removeLastChild();
533 parent.addChild(localctx);
534 }
535 }
536 this._ctx = localctx;
537 }
538 /**
539 * Get the precedence level for the top-most precedence rule.
540 *
541 * @returns The precedence level for the top-most precedence rule, or -1 if
542 * the parser context is not nested within a precedence rule.
543 */
544 get precedence() {
545 if (this._precedenceStack.isEmpty) {
546 return -1;
547 }
548 return this._precedenceStack.peek();
549 }
550 enterRecursionRule(localctx, state, ruleIndex, precedence) {
551 this.state = state;
552 this._precedenceStack.push(precedence);
553 this._ctx = localctx;
554 this._ctx._start = this._input.LT(1);
555 this.triggerEnterRuleEvent(); // simulates rule entry for left-recursive rules
556 }
557 /** Like {@link #enterRule} but for recursive rules.
558 * Make the current context the child of the incoming localctx.
559 */
560 pushNewRecursionContext(localctx, state, ruleIndex) {
561 let previous = this._ctx;
562 previous._parent = localctx;
563 previous.invokingState = state;
564 previous._stop = this._input.tryLT(-1);
565 this._ctx = localctx;
566 this._ctx._start = previous._start;
567 if (this._buildParseTrees) {
568 this._ctx.addChild(previous);
569 }
570 this.triggerEnterRuleEvent(); // simulates rule entry for left-recursive rules
571 }
572 unrollRecursionContexts(_parentctx) {
573 this._precedenceStack.pop();
574 this._ctx._stop = this._input.tryLT(-1);
575 let retctx = this._ctx; // save current ctx (return value)
576 // unroll so _ctx is as it was before call to recursive method
577 if (this._parseListeners.length > 0) {
578 while (this._ctx !== _parentctx) {
579 this.triggerExitRuleEvent();
580 this._ctx = this._ctx._parent;
581 }
582 }
583 else {
584 this._ctx = _parentctx;
585 }
586 // hook into tree
587 retctx._parent = _parentctx;
588 if (this._buildParseTrees && _parentctx != null) {
589 // add return ctx into invoking rule's tree
590 _parentctx.addChild(retctx);
591 }
592 }
593 getInvokingContext(ruleIndex) {
594 let p = this._ctx;
595 while (p && p.ruleIndex !== ruleIndex) {
596 p = p._parent;
597 }
598 return p;
599 }
600 get context() {
601 return this._ctx;
602 }
603 set context(ctx) {
604 this._ctx = ctx;
605 }
606 precpred(localctx, precedence) {
607 return precedence >= this._precedenceStack.peek();
608 }
609 getErrorListenerDispatch() {
610 return new ProxyParserErrorListener_1.ProxyParserErrorListener(this.getErrorListeners());
611 }
612 inContext(context) {
613 // TODO: useful in parser?
614 return false;
615 }
616 /**
617 * Checks whether or not `symbol` can follow the current state in the
618 * ATN. The behavior of this method is equivalent to the following, but is
619 * implemented such that the complete context-sensitive follow set does not
620 * need to be explicitly constructed.
621 *
622 * ```
623 * return getExpectedTokens().contains(symbol);
624 * ```
625 *
626 * @param symbol the symbol type to check
627 * @returns `true` if `symbol` can follow the current state in
628 * the ATN, otherwise `false`.
629 */
630 isExpectedToken(symbol) {
631 // return interpreter.atn.nextTokens(_ctx);
632 let atn = this.interpreter.atn;
633 let ctx = this._ctx;
634 let s = atn.states[this.state];
635 let following = atn.nextTokens(s);
636 if (following.contains(symbol)) {
637 return true;
638 }
639 // System.out.println("following "+s+"="+following);
640 if (!following.contains(Token_1.Token.EPSILON)) {
641 return false;
642 }
643 while (ctx != null && ctx.invokingState >= 0 && following.contains(Token_1.Token.EPSILON)) {
644 let invokingState = atn.states[ctx.invokingState];
645 let rt = invokingState.transition(0);
646 following = atn.nextTokens(rt.followState);
647 if (following.contains(symbol)) {
648 return true;
649 }
650 ctx = ctx._parent;
651 }
652 if (following.contains(Token_1.Token.EPSILON) && symbol === Token_1.Token.EOF) {
653 return true;
654 }
655 return false;
656 }
657 get isMatchedEOF() {
658 return this.matchedEOF;
659 }
660 /**
661 * Computes the set of input symbols which could follow the current parser
662 * state and context, as given by {@link #getState} and {@link #getContext},
663 * respectively.
664 *
665 * @see ATN#getExpectedTokens(int, RuleContext)
666 */
667 getExpectedTokens() {
668 return this.atn.getExpectedTokens(this.state, this.context);
669 }
670 getExpectedTokensWithinCurrentRule() {
671 let atn = this.interpreter.atn;
672 let s = atn.states[this.state];
673 return atn.nextTokens(s);
674 }
675 /** Get a rule's index (i.e., `RULE_ruleName` field) or -1 if not found. */
676 getRuleIndex(ruleName) {
677 let ruleIndex = this.getRuleIndexMap().get(ruleName);
678 if (ruleIndex != null) {
679 return ruleIndex;
680 }
681 return -1;
682 }
683 get ruleContext() { return this._ctx; }
684 /** Return List&lt;String&gt; of the rule names in your parser instance
685 * leading up to a call to the current rule. You could override if
686 * you want more details such as the file/line info of where
687 * in the ATN a rule is invoked.
688 *
689 * This is very useful for error messages.
690 */
691 getRuleInvocationStack(ctx = this._ctx) {
692 let p = ctx; // Workaround for Microsoft/TypeScript#14487
693 let ruleNames = this.ruleNames;
694 let stack = [];
695 while (p != null) {
696 // compute what follows who invoked us
697 let ruleIndex = p.ruleIndex;
698 if (ruleIndex < 0) {
699 stack.push("n/a");
700 }
701 else {
702 stack.push(ruleNames[ruleIndex]);
703 }
704 p = p._parent;
705 }
706 return stack;
707 }
708 /** For debugging and other purposes. */
709 getDFAStrings() {
710 let s = [];
711 for (let dfa of this._interp.atn.decisionToDFA) {
712 s.push(dfa.toString(this.vocabulary, this.ruleNames));
713 }
714 return s;
715 }
716 /** For debugging and other purposes. */
717 dumpDFA() {
718 let seenOne = false;
719 for (let dfa of this._interp.atn.decisionToDFA) {
720 if (!dfa.isEmpty) {
721 if (seenOne) {
722 console.log();
723 }
724 console.log("Decision " + dfa.decision + ":");
725 process.stdout.write(dfa.toString(this.vocabulary, this.ruleNames));
726 seenOne = true;
727 }
728 }
729 }
730 get sourceName() {
731 return this._input.sourceName;
732 }
733 get parseInfo() {
734 return Promise.resolve().then(() => require("./atn/ProfilingATNSimulator")).then((m) => {
735 let interp = this.interpreter;
736 if (interp instanceof m.ProfilingATNSimulator) {
737 return new ParseInfo_1.ParseInfo(interp);
738 }
739 return undefined;
740 });
741 }
742 /**
743 * @since 4.3
744 */
745 setProfile(profile) {
746 return __awaiter(this, void 0, void 0, function* () {
747 let m = yield Promise.resolve().then(() => require("./atn/ProfilingATNSimulator"));
748 let interp = this.interpreter;
749 if (profile) {
750 if (!(interp instanceof m.ProfilingATNSimulator)) {
751 this.interpreter = new m.ProfilingATNSimulator(this);
752 }
753 }
754 else if (interp instanceof m.ProfilingATNSimulator) {
755 this.interpreter = new ParserATNSimulator_1.ParserATNSimulator(this.atn, this);
756 }
757 this.interpreter.setPredictionMode(interp.getPredictionMode());
758 });
759 }
760 /** During a parse is sometimes useful to listen in on the rule entry and exit
761 * events as well as token matches. This is for quick and dirty debugging.
762 */
763 set isTrace(trace) {
764 if (!trace) {
765 if (this._tracer) {
766 this.removeParseListener(this._tracer);
767 this._tracer = undefined;
768 }
769 }
770 else {
771 if (this._tracer) {
772 this.removeParseListener(this._tracer);
773 }
774 else {
775 this._tracer = new TraceListener(this.ruleNames, this._input);
776 }
777 this.addParseListener(this._tracer);
778 }
779 }
780 /**
781 * Gets whether a {@link TraceListener} is registered as a parse listener
782 * for the parser.
783 */
784 get isTrace() {
785 return this._tracer != null;
786 }
787}
788/**
789 * This field maps from the serialized ATN string to the deserialized {@link ATN} with
790 * bypass alternatives.
791 *
792 * @see ATNDeserializationOptions.isGenerateRuleBypassTransitions
793 */
794Parser.bypassAltsAtnCache = new Map();
795__decorate([
796 Decorators_1.NotNull
797], Parser.prototype, "_errHandler", void 0);
798__decorate([
799 Decorators_1.NotNull
800], Parser.prototype, "match", null);
801__decorate([
802 Decorators_1.NotNull
803], Parser.prototype, "matchWildcard", null);
804__decorate([
805 Decorators_1.NotNull
806], Parser.prototype, "getParseListeners", null);
807__decorate([
808 __param(0, Decorators_1.NotNull)
809], Parser.prototype, "addParseListener", null);
810__decorate([
811 Decorators_1.NotNull
812], Parser.prototype, "getATNWithBypassAlts", null);
813__decorate([
814 Decorators_1.NotNull,
815 __param(0, Decorators_1.NotNull)
816], Parser.prototype, "errorHandler", null);
817__decorate([
818 Decorators_1.Override
819], Parser.prototype, "inputStream", null);
820__decorate([
821 Decorators_1.NotNull
822], Parser.prototype, "currentToken", null);
823__decorate([
824 __param(0, Decorators_1.NotNull)
825], Parser.prototype, "enterRule", null);
826__decorate([
827 Decorators_1.Override,
828 __param(0, Decorators_1.Nullable)
829], Parser.prototype, "precpred", null);
830__decorate([
831 Decorators_1.Override
832], Parser.prototype, "getErrorListenerDispatch", null);
833__decorate([
834 Decorators_1.NotNull
835], Parser.prototype, "getExpectedTokens", null);
836__decorate([
837 Decorators_1.NotNull
838], Parser.prototype, "getExpectedTokensWithinCurrentRule", null);
839__decorate([
840 Decorators_1.Override
841], Parser.prototype, "parseInfo", null);
842exports.Parser = Parser;
843//# sourceMappingURL=Parser.js.map
\No newline at end of file