001: package persistence.antlr.debug;
002:
003: /* ANTLR Translator Generator
004: * Project led by Terence Parr at http://www.jGuru.com
005: * Software rights: http://www.antlr.org/license.html
006: */
007:
008: import persistence.antlr.*;
009: import persistence.antlr.collections.impl.BitSet;
010:
011: import java.util.Stack;
012:
013: /** Override the standard matching and rule entry/exit routines
014: * to build parse trees. This class is useful for 2.7.3 where
015: * you can specify a superclass like
016: *
017: * class TinyCParser extends Parser(ParseTreeDebugParser);
018: */
019: public class ParseTreeDebugParser extends LLkParser {
020: /** Each new rule invocation must have it's own subtree. Tokens
021: * are added to the current root so we must have a stack of subtree roots.
022: */
023: protected Stack currentParseTreeRoot = new Stack();
024:
025: /** Track most recently created parse subtree so that when parsing
026: * is finished, we can get to the root.
027: */
028: protected ParseTreeRule mostRecentParseTreeRoot = null;
029:
030: /** For every rule replacement with a production, we bump up count. */
031: protected int numberOfDerivationSteps = 1; // n replacements plus step 0
032:
033: public ParseTreeDebugParser(int k_) {
034: super (k_);
035: }
036:
037: public ParseTreeDebugParser(ParserSharedInputState state, int k_) {
038: super (state, k_);
039: }
040:
041: public ParseTreeDebugParser(TokenBuffer tokenBuf, int k_) {
042: super (tokenBuf, k_);
043: }
044:
045: public ParseTreeDebugParser(TokenStream lexer, int k_) {
046: super (lexer, k_);
047: }
048:
049: public ParseTree getParseTree() {
050: return mostRecentParseTreeRoot;
051: }
052:
053: public int getNumberOfDerivationSteps() {
054: return numberOfDerivationSteps;
055: }
056:
057: public void match(int i) throws MismatchedTokenException,
058: TokenStreamException {
059: addCurrentTokenToParseTree();
060: super .match(i);
061: }
062:
063: public void match(BitSet bitSet) throws MismatchedTokenException,
064: TokenStreamException {
065: addCurrentTokenToParseTree();
066: super .match(bitSet);
067: }
068:
069: public void matchNot(int i) throws MismatchedTokenException,
070: TokenStreamException {
071: addCurrentTokenToParseTree();
072: super .matchNot(i);
073: }
074:
075: /** This adds LT(1) to the current parse subtree. Note that the match()
076: * routines add the node before checking for correct match. This means
077: * that, upon mismatched token, there will a token node in the tree
078: * corresponding to where that token was expected. For no viable
079: * alternative errors, no node will be in the tree as nothing was
080: * matched() (the lookahead failed to predict an alternative).
081: */
082: protected void addCurrentTokenToParseTree()
083: throws TokenStreamException {
084: if (inputState.guessing > 0) {
085: return;
086: }
087: ParseTreeRule root = (ParseTreeRule) currentParseTreeRoot
088: .peek();
089: ParseTreeToken tokenNode = null;
090: if (LA(1) == Token.EOF_TYPE) {
091: tokenNode = new ParseTreeToken(
092: new persistence.antlr.CommonToken("EOF"));
093: } else {
094: tokenNode = new ParseTreeToken(LT(1));
095: }
096: root.addChild(tokenNode);
097: }
098:
099: /** Create a rule node, add to current tree, and make it current root */
100: public void traceIn(String s) throws TokenStreamException {
101: if (inputState.guessing > 0) {
102: return;
103: }
104: ParseTreeRule subRoot = new ParseTreeRule(s);
105: if (currentParseTreeRoot.size() > 0) {
106: ParseTreeRule oldRoot = (ParseTreeRule) currentParseTreeRoot
107: .peek();
108: oldRoot.addChild(subRoot);
109: }
110: currentParseTreeRoot.push(subRoot);
111: numberOfDerivationSteps++;
112: }
113:
114: /** Pop current root; back to adding to old root */
115: public void traceOut(String s) throws TokenStreamException {
116: if (inputState.guessing > 0) {
117: return;
118: }
119: mostRecentParseTreeRoot = (ParseTreeRule) currentParseTreeRoot
120: .pop();
121: }
122:
123: }
|