package org.antlr.v4.runtime.tree;
import org.antlr.v4.runtime.misc.IntegerStack;
import java.util.ArrayDeque;
import java.util.Deque;
public class IterativeParseTreeWalker extends ParseTreeWalker {
@Override
public void walk(ParseTreeListener listener, ParseTree t) {
final Deque<ParseTree> nodeStack = new ArrayDeque<ParseTree>();
final IntegerStack indexStack = new IntegerStack();
ParseTree currentNode = t;
int currentIndex = 0;
while (currentNode != null) {
if (currentNode instanceof ErrorNode) {
listener.visitErrorNode((ErrorNode) currentNode);
}
else if (currentNode instanceof TerminalNode) {
listener.visitTerminal((TerminalNode) currentNode);
}
else {
final RuleNode r = (RuleNode) currentNode;
enterRule(listener, r);
}
if (currentNode.getChildCount() > 0) {
nodeStack.push(currentNode);
indexStack.push(currentIndex);
currentIndex = 0;
currentNode = currentNode.getChild(0);
continue;
}
do {
if (currentNode instanceof RuleNode) {
exitRule(listener, (RuleNode) currentNode);
}
if (nodeStack.isEmpty()) {
currentNode = null;
currentIndex = 0;
break;
}
currentNode = nodeStack.peek().getChild(++currentIndex);
if (currentNode != null) {
break;
}
currentNode = nodeStack.pop();
currentIndex = indexStack.pop();
} while (currentNode != null);
}
}
}