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 | } |
---|