1 /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
2 * Use of this file is governed by the BSD 3-clause license that
3 * can be found in the LICENSE.txt file in the project root.
6 #include "support/CPPUtils.h"
8 #include "tree/ParseTreeListener.h"
9 #include "tree/ParseTree.h"
10 #include "tree/ErrorNode.h"
12 #include "IterativeParseTreeWalker.h"
14 using namespace antlr4::tree;
16 void IterativeParseTreeWalker::walk(ParseTreeListener *listener, ParseTree *t) const {
18 std::vector<ParseTree *> nodeStack;
19 std::vector<size_t> indexStack;
21 ParseTree *currentNode = t;
22 size_t currentIndex = 0;
24 while (currentNode != nullptr) {
26 if (antlrcpp::is<ErrorNode *>(currentNode)) {
27 listener->visitErrorNode(dynamic_cast<ErrorNode *>(currentNode));
28 } else if (antlrcpp::is<TerminalNode *>(currentNode)) {
29 listener->visitTerminal((TerminalNode *)currentNode);
31 enterRule(listener, currentNode);
34 // Move down to first child, if it exists.
35 if (!currentNode->children.empty()) {
36 nodeStack.push_back(currentNode);
37 indexStack.push_back(currentIndex);
39 currentNode = currentNode->children[0];
43 // No child nodes, so walk tree.
46 if (!antlrcpp::is<TerminalNode *>(currentNode)) {
47 exitRule(listener, currentNode);
50 // No parent, so no siblings.
51 if (nodeStack.empty()) {
52 currentNode = nullptr;
57 // Move to next sibling if possible.
58 if (nodeStack.back()->children.size() > ++currentIndex) {
59 currentNode = nodeStack.back()->children[currentIndex];
63 // No next sibling, so move up.
64 currentNode = nodeStack.back();
66 currentIndex = indexStack.back();
67 indexStack.pop_back();
69 } while (currentNode != nullptr);