#include "support/CPPUtils.h"
#include "support/Casts.h"
#include "tree/ParseTreeListener.h"
#include "tree/ParseTree.h"
#include "tree/ErrorNode.h"
#include "IterativeParseTreeWalker.h"
using namespace antlr4::tree;
using namespace antlrcpp;
void IterativeParseTreeWalker::walk(ParseTreeListener *listener, ParseTree *t) const {
std::vector<std::pair<ParseTree*, size_t>> stack;
ParseTree *currentNode = t;
size_t currentIndex = 0;
while (currentNode != nullptr) {
if (ErrorNode::is(*currentNode)) {
listener->visitErrorNode(downCast<ErrorNode*>(currentNode));
} else if (TerminalNode::is(*currentNode)) {
listener->visitTerminal(downCast<TerminalNode*>(currentNode));
} else {
enterRule(listener, currentNode);
}
if (!currentNode->children.empty()) {
stack.push_back(std::make_pair(currentNode, currentIndex));
currentIndex = 0;
currentNode = currentNode->children[0];
continue;
}
do {
if (!TerminalNode::is(*currentNode)) {
exitRule(listener, currentNode);
}
if (stack.empty()) {
currentNode = nullptr;
currentIndex = 0;
break;
}
if (stack.back().first->children.size() > ++currentIndex) {
currentNode = stack.back().first->children[currentIndex];
break;
}
std::tie(currentNode, currentIndex) = stack.back();
stack.pop_back();
} while (currentNode != nullptr);
}
}