[1] | 1 | package antlr.debug; |
---|
| 2 | |
---|
| 3 | /* ANTLR Translator Generator |
---|
| 4 | * Project led by Terence Parr at http://www.cs.usfca.edu |
---|
| 5 | * Software rights: http://www.antlr.org/license.html |
---|
| 6 | */ |
---|
| 7 | |
---|
| 8 | import antlr.*; |
---|
| 9 | import antlr.collections.impl.BitSet; |
---|
| 10 | |
---|
| 11 | import java.util.Stack; |
---|
| 12 | |
---|
| 13 | /** Override the standard matching and rule entry/exit routines |
---|
| 14 | * to build parse trees. This class is useful for 2.7.3 where |
---|
| 15 | * you can specify a superclass like |
---|
| 16 | * |
---|
| 17 | * class TinyCParser extends Parser(ParseTreeDebugParser); |
---|
| 18 | */ |
---|
| 19 | public class ParseTreeDebugParser extends LLkParser { |
---|
| 20 | /** Each new rule invocation must have it's own subtree. Tokens |
---|
| 21 | * are added to the current root so we must have a stack of subtree roots. |
---|
| 22 | */ |
---|
| 23 | protected Stack currentParseTreeRoot = new Stack(); |
---|
| 24 | |
---|
| 25 | /** Track most recently created parse subtree so that when parsing |
---|
| 26 | * is finished, we can get to the root. |
---|
| 27 | */ |
---|
| 28 | protected ParseTreeRule mostRecentParseTreeRoot = null; |
---|
| 29 | |
---|
| 30 | /** For every rule replacement with a production, we bump up count. */ |
---|
| 31 | protected int numberOfDerivationSteps = 1; // n replacements plus step 0 |
---|
| 32 | |
---|
| 33 | public ParseTreeDebugParser(int k_) { |
---|
| 34 | super(k_); |
---|
| 35 | } |
---|
| 36 | |
---|
| 37 | public ParseTreeDebugParser(ParserSharedInputState state, int k_) { |
---|
| 38 | super(state,k_); |
---|
| 39 | } |
---|
| 40 | |
---|
| 41 | public ParseTreeDebugParser(TokenBuffer tokenBuf, int k_) { |
---|
| 42 | super(tokenBuf, k_); |
---|
| 43 | } |
---|
| 44 | |
---|
| 45 | public ParseTreeDebugParser(TokenStream lexer, int k_) { |
---|
| 46 | super(lexer,k_); |
---|
| 47 | } |
---|
| 48 | |
---|
| 49 | public ParseTree getParseTree() { |
---|
| 50 | return mostRecentParseTreeRoot; |
---|
| 51 | } |
---|
| 52 | |
---|
| 53 | public int getNumberOfDerivationSteps() { |
---|
| 54 | return numberOfDerivationSteps; |
---|
| 55 | } |
---|
| 56 | |
---|
| 57 | public void match(int i) throws MismatchedTokenException, TokenStreamException { |
---|
| 58 | addCurrentTokenToParseTree(); |
---|
| 59 | super.match(i); |
---|
| 60 | } |
---|
| 61 | |
---|
| 62 | public void match(BitSet bitSet) throws MismatchedTokenException, TokenStreamException { |
---|
| 63 | addCurrentTokenToParseTree(); |
---|
| 64 | super.match(bitSet); |
---|
| 65 | } |
---|
| 66 | |
---|
| 67 | public void matchNot(int i) throws MismatchedTokenException, TokenStreamException { |
---|
| 68 | addCurrentTokenToParseTree(); |
---|
| 69 | super.matchNot(i); |
---|
| 70 | } |
---|
| 71 | |
---|
| 72 | /** This adds LT(1) to the current parse subtree. Note that the match() |
---|
| 73 | * routines add the node before checking for correct match. This means |
---|
| 74 | * that, upon mismatched token, there will a token node in the tree |
---|
| 75 | * corresponding to where that token was expected. For no viable |
---|
| 76 | * alternative errors, no node will be in the tree as nothing was |
---|
| 77 | * matched() (the lookahead failed to predict an alternative). |
---|
| 78 | */ |
---|
| 79 | protected void addCurrentTokenToParseTree() throws TokenStreamException { |
---|
| 80 | if (inputState.guessing>0) { |
---|
| 81 | return; |
---|
| 82 | } |
---|
| 83 | ParseTreeRule root = (ParseTreeRule)currentParseTreeRoot.peek(); |
---|
| 84 | ParseTreeToken tokenNode = null; |
---|
| 85 | if ( LA(1)==Token.EOF_TYPE ) { |
---|
| 86 | tokenNode = new ParseTreeToken(new antlr.CommonToken("EOF")); |
---|
| 87 | } |
---|
| 88 | else { |
---|
| 89 | tokenNode = new ParseTreeToken(LT(1)); |
---|
| 90 | } |
---|
| 91 | root.addChild(tokenNode); |
---|
| 92 | } |
---|
| 93 | |
---|
| 94 | /** Create a rule node, add to current tree, and make it current root */ |
---|
| 95 | public void traceIn(String s) throws TokenStreamException { |
---|
| 96 | if (inputState.guessing>0) { |
---|
| 97 | return; |
---|
| 98 | } |
---|
| 99 | ParseTreeRule subRoot = new ParseTreeRule(s); |
---|
| 100 | if ( currentParseTreeRoot.size()>0 ) { |
---|
| 101 | ParseTreeRule oldRoot = (ParseTreeRule)currentParseTreeRoot.peek(); |
---|
| 102 | oldRoot.addChild(subRoot); |
---|
| 103 | } |
---|
| 104 | currentParseTreeRoot.push(subRoot); |
---|
| 105 | numberOfDerivationSteps++; |
---|
| 106 | } |
---|
| 107 | |
---|
| 108 | /** Pop current root; back to adding to old root */ |
---|
| 109 | public void traceOut(String s) throws TokenStreamException { |
---|
| 110 | if (inputState.guessing>0) { |
---|
| 111 | return; |
---|
| 112 | } |
---|
| 113 | mostRecentParseTreeRoot = (ParseTreeRule)currentParseTreeRoot.pop(); |
---|
| 114 | } |
---|
| 115 | |
---|
| 116 | } |
---|