package antlr.debug;
/* ANTLR Translator Generator
* Project led by Terence Parr at http://www.cs.usfca.edu
* Software rights: http://www.antlr.org/license.html
*/
import antlr.*;
import antlr.collections.impl.
BitSet;
import java.util.
Stack;
/** Override the standard matching and rule entry/exit routines
* to build parse trees. This class is useful for 2.7.3 where
* you can specify a superclass like
*
* class TinyCParser extends Parser(ParseTreeDebugParser);
*/
public class
ParseTreeDebugParser extends
LLkParser {
/** Each new rule invocation must have it's own subtree. Tokens
* are added to the current root so we must have a stack of subtree roots.
*/
protected
Stack currentParseTreeRoot = new
Stack();
/** Track most recently created parse subtree so that when parsing
* is finished, we can get to the root.
*/
protected
ParseTreeRule mostRecentParseTreeRoot = null;
/** For every rule replacement with a production, we bump up count. */
protected int
numberOfDerivationSteps = 1; // n replacements plus step 0
public
ParseTreeDebugParser(int
k_) {
super(
k_);
}
public
ParseTreeDebugParser(
ParserSharedInputState state, int
k_) {
super(
state,
k_);
}
public
ParseTreeDebugParser(
TokenBuffer tokenBuf, int
k_) {
super(
tokenBuf,
k_);
}
public
ParseTreeDebugParser(
TokenStream lexer, int
k_) {
super(
lexer,
k_);
}
public
ParseTree getParseTree() {
return
mostRecentParseTreeRoot;
}
public int
getNumberOfDerivationSteps() {
return
numberOfDerivationSteps;
}
public void
match(int
i) throws
MismatchedTokenException,
TokenStreamException {
addCurrentTokenToParseTree();
super.match(
i);
}
public void
match(
BitSet bitSet) throws
MismatchedTokenException,
TokenStreamException {
addCurrentTokenToParseTree();
super.match(
bitSet);
}
public void
matchNot(int
i) throws
MismatchedTokenException,
TokenStreamException {
addCurrentTokenToParseTree();
super.matchNot(
i);
}
/** This adds LT(1) to the current parse subtree. Note that the match()
* routines add the node before checking for correct match. This means
* that, upon mismatched token, there will a token node in the tree
* corresponding to where that token was expected. For no viable
* alternative errors, no node will be in the tree as nothing was
* matched() (the lookahead failed to predict an alternative).
*/
protected void
addCurrentTokenToParseTree() throws
TokenStreamException {
if (
inputState.
guessing>0) {
return;
}
ParseTreeRule root = (
ParseTreeRule)
currentParseTreeRoot.
peek();
ParseTreeToken tokenNode = null;
if (
LA(1)==
Token.
EOF_TYPE ) {
tokenNode = new
ParseTreeToken(new antlr.
CommonToken("EOF"));
}
else {
tokenNode = new
ParseTreeToken(
LT(1));
}
root.
addChild(
tokenNode);
}
/** Create a rule node, add to current tree, and make it current root */
public void
traceIn(
String s) throws
TokenStreamException {
if (
inputState.
guessing>0) {
return;
}
ParseTreeRule subRoot = new
ParseTreeRule(
s);
if (
currentParseTreeRoot.
size()>0 ) {
ParseTreeRule oldRoot = (
ParseTreeRule)
currentParseTreeRoot.
peek();
oldRoot.
addChild(
subRoot);
}
currentParseTreeRoot.
push(
subRoot);
numberOfDerivationSteps++;
}
/** Pop current root; back to adding to old root */
public void
traceOut(
String s) throws
TokenStreamException {
if (
inputState.
guessing>0) {
return;
}
mostRecentParseTreeRoot = (
ParseTreeRule)
currentParseTreeRoot.
pop();
}
}