UNPKG

antlr4ts

Version:

ANTLR 4 runtime for JavaScript written in Typescript

300 lines 11 kB
"use strict"; /*! * Copyright 2016 The ANTLR Project. All rights reserved. * Licensed under the BSD-3-Clause license. See LICENSE file in the project root for license information. */ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 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; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ParserRuleContext = void 0; // ConvertTo-TS run at 2016-10-04T11:26:56.6285494-07:00 const ErrorNode_1 = require("./tree/ErrorNode"); const Interval_1 = require("./misc/Interval"); const Decorators_1 = require("./Decorators"); const RuleContext_1 = require("./RuleContext"); const TerminalNode_1 = require("./tree/TerminalNode"); /** A rule invocation record for parsing. * * Contains all of the information about the current rule not stored in the * RuleContext. It handles parse tree children list, Any ATN state * tracing, and the default values available for rule invocations: * start, stop, rule index, current alt number. * * Subclasses made for each rule and grammar track the parameters, * return values, locals, and labels specific to that rule. These * are the objects that are returned from rules. * * Note text is not an actual field of a rule return value; it is computed * from start and stop using the input stream's toString() method. I * could add a ctor to this so that we can pass in and store the input * stream, but I'm not sure we want to do that. It would seem to be undefined * to get the .text property anyway if the rule matches tokens from multiple * input streams. * * I do not use getters for fields of objects that are used simply to * group values such as this aggregate. The getters/setters are there to * satisfy the superclass interface. */ class ParserRuleContext extends RuleContext_1.RuleContext { constructor(parent, invokingStateNumber) { if (invokingStateNumber == null) { super(); } else { super(parent, invokingStateNumber); } } static emptyContext() { return ParserRuleContext.EMPTY; } /** * COPY a ctx (I'm deliberately not using copy constructor) to avoid * confusion with creating node with parent. Does not copy children * (except error leaves). * * This is used in the generated parser code to flip a generic XContext * node for rule X to a YContext for alt label Y. In that sense, it is not * really a generic copy function. * * If we do an error sync() at start of a rule, we might add error nodes * to the generic XContext so this function must copy those nodes to the * YContext as well else they are lost! */ copyFrom(ctx) { this._parent = ctx._parent; this.invokingState = ctx.invokingState; this._start = ctx._start; this._stop = ctx._stop; // copy any error nodes to alt label node if (ctx.children) { this.children = []; // reset parent pointer for any error nodes for (let child of ctx.children) { if (child instanceof ErrorNode_1.ErrorNode) { this.addChild(child); } } } } // Double dispatch methods for listeners enterRule(listener) { // intentionally empty } exitRule(listener) { // intentionally empty } /** Add a parse tree node to this as a child. Works for * internal and leaf nodes. Does not set parent link; * other add methods must do that. Other addChild methods * call this. * * We cannot set the parent pointer of the incoming node * because the existing interfaces do not have a setParent() * method and I don't want to break backward compatibility for this. * * @since 4.7 */ addAnyChild(t) { if (!this.children) { this.children = [t]; } else { this.children.push(t); } return t; } addChild(t) { let result; if (t instanceof TerminalNode_1.TerminalNode) { t.setParent(this); this.addAnyChild(t); return; } else if (t instanceof RuleContext_1.RuleContext) { // Does not set parent link this.addAnyChild(t); return; } else { // Deprecated code path t = new TerminalNode_1.TerminalNode(t); this.addAnyChild(t); t.setParent(this); return t; } } addErrorNode(node) { if (node instanceof ErrorNode_1.ErrorNode) { const errorNode = node; errorNode.setParent(this); return this.addAnyChild(errorNode); } else { // deprecated path const badToken = node; let t = new ErrorNode_1.ErrorNode(badToken); this.addAnyChild(t); t.setParent(this); return t; } } // public void trace(int s) { // if ( states==null ) states = new ArrayList<Integer>(); // states.add(s); // } /** Used by enterOuterAlt to toss out a RuleContext previously added as * we entered a rule. If we have # label, we will need to remove * generic ruleContext object. */ removeLastChild() { if (this.children) { this.children.pop(); } } get parent() { let parent = super.parent; if (parent === undefined || parent instanceof ParserRuleContext) { return parent; } throw new TypeError("Invalid parent type for ParserRuleContext"); } // Note: in TypeScript, order or arguments reversed getChild(i, ctxType) { if (!this.children || i < 0 || i >= this.children.length) { throw new RangeError("index parameter must be between >= 0 and <= number of children."); } if (ctxType == null) { return this.children[i]; } let result = this.tryGetChild(i, ctxType); if (result === undefined) { throw new Error("The specified node does not exist"); } return result; } tryGetChild(i, ctxType) { if (!this.children || i < 0 || i >= this.children.length) { return undefined; } let j = -1; // what node with ctxType have we found? for (let o of this.children) { if (o instanceof ctxType) { j++; if (j === i) { return o; } } } return undefined; } getToken(ttype, i) { let result = this.tryGetToken(ttype, i); if (result === undefined) { throw new Error("The specified token does not exist"); } return result; } tryGetToken(ttype, i) { if (!this.children || i < 0 || i >= this.children.length) { return undefined; } let j = -1; // what token with ttype have we found? for (let o of this.children) { if (o instanceof TerminalNode_1.TerminalNode) { let symbol = o.symbol; if (symbol.type === ttype) { j++; if (j === i) { return o; } } } } return undefined; } getTokens(ttype) { let tokens = []; if (!this.children) { return tokens; } for (let o of this.children) { if (o instanceof TerminalNode_1.TerminalNode) { let symbol = o.symbol; if (symbol.type === ttype) { tokens.push(o); } } } return tokens; } get ruleContext() { return this; } // NOTE: argument order change from Java version getRuleContext(i, ctxType) { return this.getChild(i, ctxType); } tryGetRuleContext(i, ctxType) { return this.tryGetChild(i, ctxType); } getRuleContexts(ctxType) { let contexts = []; if (!this.children) { return contexts; } for (let o of this.children) { if (o instanceof ctxType) { contexts.push(o); } } return contexts; } get childCount() { return this.children ? this.children.length : 0; } get sourceInterval() { if (!this._start) { return Interval_1.Interval.INVALID; } if (!this._stop || this._stop.tokenIndex < this._start.tokenIndex) { return Interval_1.Interval.of(this._start.tokenIndex, this._start.tokenIndex - 1); // empty } return Interval_1.Interval.of(this._start.tokenIndex, this._stop.tokenIndex); } /** * Get the initial token in this context. * Note that the range from start to stop is inclusive, so for rules that do not consume anything * (for example, zero length or error productions) this token may exceed stop. */ get start() { return this._start; } /** * Get the final token in this context. * Note that the range from start to stop is inclusive, so for rules that do not consume anything * (for example, zero length or error productions) this token may precede start. */ get stop() { return this._stop; } /** Used for rule context info debugging during parse-time, not so much for ATN debugging */ toInfoString(recognizer) { let rules = recognizer.getRuleInvocationStack(this).reverse(); return "ParserRuleContext" + rules + "{" + "start=" + this._start + ", stop=" + this._stop + "}"; } } ParserRuleContext.EMPTY = new ParserRuleContext(); __decorate([ Decorators_1.Override ], ParserRuleContext.prototype, "parent", null); __decorate([ Decorators_1.Override ], ParserRuleContext.prototype, "childCount", null); __decorate([ Decorators_1.Override ], ParserRuleContext.prototype, "sourceInterval", null); exports.ParserRuleContext = ParserRuleContext; //# sourceMappingURL=ParserRuleContext.js.map