summaryrefslogtreecommitdiff
path: root/deps/v8/third_party/antlr4/runtime/Cpp/runtime/src/tree/IterativeParseTreeWalker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/third_party/antlr4/runtime/Cpp/runtime/src/tree/IterativeParseTreeWalker.cpp')
-rw-r--r--deps/v8/third_party/antlr4/runtime/Cpp/runtime/src/tree/IterativeParseTreeWalker.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/deps/v8/third_party/antlr4/runtime/Cpp/runtime/src/tree/IterativeParseTreeWalker.cpp b/deps/v8/third_party/antlr4/runtime/Cpp/runtime/src/tree/IterativeParseTreeWalker.cpp
new file mode 100644
index 0000000000..66cfc91d1d
--- /dev/null
+++ b/deps/v8/third_party/antlr4/runtime/Cpp/runtime/src/tree/IterativeParseTreeWalker.cpp
@@ -0,0 +1,71 @@
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#include "support/CPPUtils.h"
+
+#include "tree/ErrorNode.h"
+#include "tree/ParseTree.h"
+#include "tree/ParseTreeListener.h"
+
+#include "IterativeParseTreeWalker.h"
+
+using namespace antlr4::tree;
+
+void IterativeParseTreeWalker::walk(ParseTreeListener* listener,
+ ParseTree* t) const {
+ std::vector<ParseTree*> nodeStack;
+ std::vector<size_t> indexStack;
+
+ ParseTree* currentNode = t;
+ size_t currentIndex = 0;
+
+ while (currentNode != nullptr) {
+ // pre-order visit
+ if (antlrcpp::is<ErrorNode*>(currentNode)) {
+ listener->visitErrorNode(dynamic_cast<ErrorNode*>(currentNode));
+ } else if (antlrcpp::is<TerminalNode*>(currentNode)) {
+ listener->visitTerminal((TerminalNode*)currentNode);
+ } else {
+ enterRule(listener, currentNode);
+ }
+
+ // Move down to first child, if it exists.
+ if (!currentNode->children.empty()) {
+ nodeStack.push_back(currentNode);
+ indexStack.push_back(currentIndex);
+ currentIndex = 0;
+ currentNode = currentNode->children[0];
+ continue;
+ }
+
+ // No child nodes, so walk tree.
+ do {
+ // post-order visit
+ if (!antlrcpp::is<TerminalNode*>(currentNode)) {
+ exitRule(listener, currentNode);
+ }
+
+ // No parent, so no siblings.
+ if (nodeStack.empty()) {
+ currentNode = nullptr;
+ currentIndex = 0;
+ break;
+ }
+
+ // Move to next sibling if possible.
+ if (nodeStack.back()->children.size() > ++currentIndex) {
+ currentNode = nodeStack.back()->children[currentIndex];
+ break;
+ }
+
+ // No next sibling, so move up.
+ currentNode = nodeStack.back();
+ nodeStack.pop_back();
+ currentIndex = indexStack.back();
+ indexStack.pop_back();
+
+ } while (currentNode != nullptr);
+ }
+}