UNPKG

antlr4ts

Version:

ANTLR 4 runtime for JavaScript written in Typescript

104 lines 4.31 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. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ParseTreeWalker = void 0; const ErrorNode_1 = require("./ErrorNode"); const TerminalNode_1 = require("./TerminalNode"); const RuleNode_1 = require("./RuleNode"); class ParseTreeWalker { /** * Performs a walk on the given parse tree starting at the root and going down recursively * with depth-first search. On each node, {@link ParseTreeWalker#enterRule} is called before * recursively walking down into child nodes, then * {@link ParseTreeWalker#exitRule} is called after the recursive call to wind up. * @param listener The listener used by the walker to process grammar rules * @param t The parse tree to be walked on */ walk(listener, t) { let nodeStack = []; let indexStack = []; let currentNode = t; let currentIndex = 0; while (currentNode) { // pre-order visit if (currentNode instanceof ErrorNode_1.ErrorNode) { if (listener.visitErrorNode) { listener.visitErrorNode(currentNode); } } else if (currentNode instanceof TerminalNode_1.TerminalNode) { if (listener.visitTerminal) { listener.visitTerminal(currentNode); } } else { this.enterRule(listener, currentNode); } // Move down to first child, if exists if (currentNode.childCount > 0) { nodeStack.push(currentNode); indexStack.push(currentIndex); currentIndex = 0; currentNode = currentNode.getChild(0); continue; } // No child nodes, so walk tree do { // post-order visit if (currentNode instanceof RuleNode_1.RuleNode) { this.exitRule(listener, currentNode); } // No parent, so no siblings if (nodeStack.length === 0) { currentNode = undefined; currentIndex = 0; break; } // Move to next sibling if possible let last = nodeStack[nodeStack.length - 1]; currentIndex++; currentNode = currentIndex < last.childCount ? last.getChild(currentIndex) : undefined; if (currentNode) { break; } // No next sibling, so move up currentNode = nodeStack.pop(); currentIndex = indexStack.pop(); } while (currentNode); } } /** * Enters a grammar rule by first triggering the generic event {@link ParseTreeListener#enterEveryRule} * then by triggering the event specific to the given parse tree node * @param listener The listener responding to the trigger events * @param r The grammar rule containing the rule context */ enterRule(listener, r) { let ctx = r.ruleContext; if (listener.enterEveryRule) { listener.enterEveryRule(ctx); } ctx.enterRule(listener); } /** * Exits a grammar rule by first triggering the event specific to the given parse tree node * then by triggering the generic event {@link ParseTreeListener#exitEveryRule} * @param listener The listener responding to the trigger events * @param r The grammar rule containing the rule context */ exitRule(listener, r) { let ctx = r.ruleContext; ctx.exitRule(listener); if (listener.exitEveryRule) { listener.exitEveryRule(ctx); } } } exports.ParseTreeWalker = ParseTreeWalker; (function (ParseTreeWalker) { ParseTreeWalker.DEFAULT = new ParseTreeWalker(); })(ParseTreeWalker = exports.ParseTreeWalker || (exports.ParseTreeWalker = {})); //# sourceMappingURL=ParseTreeWalker.js.map