1 /* 2 [The "BSD license"] 3 Copyright (c) 2005-2009 Terence Parr 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions 8 are met: 9 1. Redistributions of source code must retain the above copyright 10 notice, this list of conditions and the following disclaimer. 11 2. Redistributions in binary form must reproduce the above copyright 12 notice, this list of conditions and the following disclaimer in the 13 documentation and/or other materials provided with the distribution. 14 3. The name of the author may not be used to endorse or promote products 15 derived from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 package org.antlr.runtime.debug; 29 30 import org.antlr.runtime.Token; 31 import org.antlr.runtime.TokenStream; 32 import org.antlr.runtime.RecognitionException; 33 import org.antlr.runtime.tree.TreeAdaptor; 34 35 /** A TreeAdaptor proxy that fires debugging events to a DebugEventListener 36 * delegate and uses the TreeAdaptor delegate to do the actual work. All 37 * AST events are triggered by this adaptor; no code gen changes are needed 38 * in generated rules. Debugging events are triggered *after* invoking 39 * tree adaptor routines. 40 * 41 * Trees created with actions in rewrite actions like "-> ^(ADD {foo} {bar})" 42 * cannot be tracked as they might not use the adaptor to create foo, bar. 43 * The debug listener has to deal with tree node IDs for which it did 44 * not see a createNode event. A single <unknown> node is sufficient even 45 * if it represents a whole tree. 46 */ 47 public class DebugTreeAdaptor implements TreeAdaptor { 48 protected DebugEventListener dbg; 49 protected TreeAdaptor adaptor; 50 DebugTreeAdaptor(DebugEventListener dbg, TreeAdaptor adaptor)51 public DebugTreeAdaptor(DebugEventListener dbg, TreeAdaptor adaptor) { 52 this.dbg = dbg; 53 this.adaptor = adaptor; 54 } 55 56 @Override create(Token payload)57 public Object create(Token payload) { 58 if ( payload.getTokenIndex() < 0 ) { 59 // could be token conjured up during error recovery 60 return create(payload.getType(), payload.getText()); 61 } 62 Object node = adaptor.create(payload); 63 dbg.createNode(node, payload); 64 return node; 65 } 66 67 @Override errorNode(TokenStream input, Token start, Token stop, RecognitionException e)68 public Object errorNode(TokenStream input, Token start, Token stop, 69 RecognitionException e) 70 { 71 Object node = adaptor.errorNode(input, start, stop, e); 72 if ( node!=null ) { 73 dbg.errorNode(node); 74 } 75 return node; 76 } 77 78 @Override dupTree(Object tree)79 public Object dupTree(Object tree) { 80 Object t = adaptor.dupTree(tree); 81 // walk the tree and emit create and add child events 82 // to simulate what dupTree has done. dupTree does not call this debug 83 // adapter so I must simulate. 84 simulateTreeConstruction(t); 85 return t; 86 } 87 88 /** ^(A B C): emit create A, create B, add child, ...*/ simulateTreeConstruction(Object t)89 protected void simulateTreeConstruction(Object t) { 90 dbg.createNode(t); 91 int n = adaptor.getChildCount(t); 92 for (int i=0; i<n; i++) { 93 Object child = adaptor.getChild(t, i); 94 simulateTreeConstruction(child); 95 dbg.addChild(t, child); 96 } 97 } 98 99 @Override dupNode(Object treeNode)100 public Object dupNode(Object treeNode) { 101 Object d = adaptor.dupNode(treeNode); 102 dbg.createNode(d); 103 return d; 104 } 105 106 @Override nil()107 public Object nil() { 108 Object node = adaptor.nil(); 109 dbg.nilNode(node); 110 return node; 111 } 112 113 @Override isNil(Object tree)114 public boolean isNil(Object tree) { 115 return adaptor.isNil(tree); 116 } 117 118 @Override addChild(Object t, Object child)119 public void addChild(Object t, Object child) { 120 if ( t==null || child==null ) { 121 return; 122 } 123 adaptor.addChild(t,child); 124 dbg.addChild(t, child); 125 } 126 127 @Override becomeRoot(Object newRoot, Object oldRoot)128 public Object becomeRoot(Object newRoot, Object oldRoot) { 129 Object n = adaptor.becomeRoot(newRoot, oldRoot); 130 dbg.becomeRoot(newRoot, oldRoot); 131 return n; 132 } 133 134 @Override rulePostProcessing(Object root)135 public Object rulePostProcessing(Object root) { 136 return adaptor.rulePostProcessing(root); 137 } 138 addChild(Object t, Token child)139 public void addChild(Object t, Token child) { 140 Object n = this.create(child); 141 this.addChild(t, n); 142 } 143 144 @Override becomeRoot(Token newRoot, Object oldRoot)145 public Object becomeRoot(Token newRoot, Object oldRoot) { 146 Object n = this.create(newRoot); 147 adaptor.becomeRoot(n, oldRoot); 148 dbg.becomeRoot(newRoot, oldRoot); 149 return n; 150 } 151 152 @Override create(int tokenType, Token fromToken)153 public Object create(int tokenType, Token fromToken) { 154 Object node = adaptor.create(tokenType, fromToken); 155 dbg.createNode(node); 156 return node; 157 } 158 159 @Override create(int tokenType, Token fromToken, String text)160 public Object create(int tokenType, Token fromToken, String text) { 161 Object node = adaptor.create(tokenType, fromToken, text); 162 dbg.createNode(node); 163 return node; 164 } 165 166 @Override create(int tokenType, String text)167 public Object create(int tokenType, String text) { 168 Object node = adaptor.create(tokenType, text); 169 dbg.createNode(node); 170 return node; 171 } 172 173 @Override getType(Object t)174 public int getType(Object t) { 175 return adaptor.getType(t); 176 } 177 178 @Override setType(Object t, int type)179 public void setType(Object t, int type) { 180 adaptor.setType(t, type); 181 } 182 183 @Override getText(Object t)184 public String getText(Object t) { 185 return adaptor.getText(t); 186 } 187 188 @Override setText(Object t, String text)189 public void setText(Object t, String text) { 190 adaptor.setText(t, text); 191 } 192 193 @Override getToken(Object t)194 public Token getToken(Object t) { 195 return adaptor.getToken(t); 196 } 197 198 @Override setTokenBoundaries(Object t, Token startToken, Token stopToken)199 public void setTokenBoundaries(Object t, Token startToken, Token stopToken) { 200 adaptor.setTokenBoundaries(t, startToken, stopToken); 201 if ( t!=null && startToken!=null && stopToken!=null ) { 202 dbg.setTokenBoundaries( 203 t, startToken.getTokenIndex(), 204 stopToken.getTokenIndex()); 205 } 206 } 207 208 @Override getTokenStartIndex(Object t)209 public int getTokenStartIndex(Object t) { 210 return adaptor.getTokenStartIndex(t); 211 } 212 213 @Override getTokenStopIndex(Object t)214 public int getTokenStopIndex(Object t) { 215 return adaptor.getTokenStopIndex(t); 216 } 217 218 @Override getChild(Object t, int i)219 public Object getChild(Object t, int i) { 220 return adaptor.getChild(t, i); 221 } 222 223 @Override setChild(Object t, int i, Object child)224 public void setChild(Object t, int i, Object child) { 225 adaptor.setChild(t, i, child); 226 } 227 228 @Override deleteChild(Object t, int i)229 public Object deleteChild(Object t, int i) { 230 return adaptor.deleteChild(t, i); 231 } 232 233 @Override getChildCount(Object t)234 public int getChildCount(Object t) { 235 return adaptor.getChildCount(t); 236 } 237 238 @Override getUniqueID(Object node)239 public int getUniqueID(Object node) { 240 return adaptor.getUniqueID(node); 241 } 242 243 @Override getParent(Object t)244 public Object getParent(Object t) { 245 return adaptor.getParent(t); 246 } 247 248 @Override getChildIndex(Object t)249 public int getChildIndex(Object t) { 250 return adaptor.getChildIndex(t); 251 } 252 253 @Override setParent(Object t, Object parent)254 public void setParent(Object t, Object parent) { 255 adaptor.setParent(t, parent); 256 } 257 258 @Override setChildIndex(Object t, int index)259 public void setChildIndex(Object t, int index) { 260 adaptor.setChildIndex(t, index); 261 } 262 263 @Override replaceChildren(Object parent, int startChildIndex, int stopChildIndex, Object t)264 public void replaceChildren(Object parent, int startChildIndex, int stopChildIndex, Object t) { 265 adaptor.replaceChildren(parent, startChildIndex, stopChildIndex, t); 266 } 267 268 // support 269 getDebugListener()270 public DebugEventListener getDebugListener() { 271 return dbg; 272 } 273 setDebugListener(DebugEventListener dbg)274 public void setDebugListener(DebugEventListener dbg) { 275 this.dbg = dbg; 276 } 277 getTreeAdaptor()278 public TreeAdaptor getTreeAdaptor() { 279 return adaptor; 280 } 281 } 282