1/* 2 * [The "BSD licence"] 3 * Copyright (c) 2011 Terence Parr 4 * All rights reserved. 5 * 6 * Conversion to C#: 7 * Copyright (c) 2011 Sam Harwell, Pixel Mine, Inc. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33namespace Antlr.Runtime.Debug 34{ 35 using ITreeAdaptor = Antlr.Runtime.Tree.ITreeAdaptor; 36 37 /** <summary> 38 * A TreeAdaptor proxy that fires debugging events to a DebugEventListener 39 * delegate and uses the TreeAdaptor delegate to do the actual work. All 40 * AST events are triggered by this adaptor; no code gen changes are needed 41 * in generated rules. Debugging events are triggered *after* invoking 42 * tree adaptor routines. 43 * </summary> 44 * 45 * <remarks> 46 * Trees created with actions in rewrite actions like "-> ^(ADD {foo} {bar})" 47 * cannot be tracked as they might not use the adaptor to create foo, bar. 48 * The debug listener has to deal with tree node IDs for which it did 49 * not see a createNode event. A single <unknown> node is sufficient even 50 * if it represents a whole tree. 51 * </remarks> 52 */ 53 public class DebugTreeAdaptor : ITreeAdaptor 54 { 55 protected IDebugEventListener dbg; 56 protected ITreeAdaptor adaptor; 57 58 public DebugTreeAdaptor( IDebugEventListener dbg, ITreeAdaptor adaptor ) 59 { 60 this.dbg = dbg; 61 this.adaptor = adaptor; 62 } 63 64 public virtual object Create( IToken payload ) 65 { 66 if ( payload.TokenIndex < 0 ) 67 { 68 // could be token conjured up during error recovery 69 return Create( payload.Type, payload.Text ); 70 } 71 object node = adaptor.Create( payload ); 72 dbg.CreateNode( node, payload ); 73 return node; 74 } 75 76 public virtual object ErrorNode( ITokenStream input, IToken start, IToken stop, 77 RecognitionException e ) 78 { 79 object node = adaptor.ErrorNode( input, start, stop, e ); 80 if ( node != null ) 81 { 82 dbg.ErrorNode( node ); 83 } 84 return node; 85 } 86 87 public virtual object DupTree( object tree ) 88 { 89 object t = adaptor.DupTree( tree ); 90 // walk the tree and emit create and add child events 91 // to simulate what dupTree has done. dupTree does not call this debug 92 // adapter so I must simulate. 93 SimulateTreeConstruction( t ); 94 return t; 95 } 96 97 /** <summary>^(A B C): emit create A, create B, add child, ...</summary> */ 98 protected virtual void SimulateTreeConstruction( object t ) 99 { 100 dbg.CreateNode( t ); 101 int n = adaptor.GetChildCount( t ); 102 for ( int i = 0; i < n; i++ ) 103 { 104 object child = adaptor.GetChild( t, i ); 105 SimulateTreeConstruction( child ); 106 dbg.AddChild( t, child ); 107 } 108 } 109 110 public virtual object DupNode( object treeNode ) 111 { 112 object d = adaptor.DupNode( treeNode ); 113 dbg.CreateNode( d ); 114 return d; 115 } 116 117 public object DupNode(int type, object treeNode) 118 { 119 object d = adaptor.DupNode(type, treeNode); 120 dbg.CreateNode(d); 121 return d; 122 } 123 124 public object DupNode(object treeNode, string text) 125 { 126 object d = adaptor.DupNode(treeNode, text); 127 dbg.CreateNode(d); 128 return d; 129 } 130 131 public object DupNode(int type, object treeNode, string text) 132 { 133 object d = adaptor.DupNode(type, treeNode, text); 134 dbg.CreateNode(d); 135 return d; 136 } 137 138 public virtual object Nil() 139 { 140 object node = adaptor.Nil(); 141 dbg.NilNode( node ); 142 return node; 143 } 144 145 public virtual bool IsNil( object tree ) 146 { 147 return adaptor.IsNil( tree ); 148 } 149 150 public virtual void AddChild( object t, object child ) 151 { 152 if ( t == null || child == null ) 153 { 154 return; 155 } 156 adaptor.AddChild( t, child ); 157 dbg.AddChild( t, child ); 158 } 159 160 public virtual object BecomeRoot( object newRoot, object oldRoot ) 161 { 162 object n = adaptor.BecomeRoot( newRoot, oldRoot ); 163 dbg.BecomeRoot( newRoot, oldRoot ); 164 return n; 165 } 166 167 public virtual object RulePostProcessing( object root ) 168 { 169 return adaptor.RulePostProcessing( root ); 170 } 171 172 public virtual void AddChild( object t, IToken child ) 173 { 174 object n = this.Create( child ); 175 this.AddChild( t, n ); 176 } 177 178 public virtual object BecomeRoot( IToken newRoot, object oldRoot ) 179 { 180 object n = this.Create( newRoot ); 181 adaptor.BecomeRoot( n, oldRoot ); 182 dbg.BecomeRoot( newRoot, oldRoot ); 183 return n; 184 } 185 186 public virtual object Create( int tokenType, IToken fromToken ) 187 { 188 object node = adaptor.Create( tokenType, fromToken ); 189 dbg.CreateNode( node ); 190 return node; 191 } 192 193 public virtual object Create( int tokenType, IToken fromToken, string text ) 194 { 195 object node = adaptor.Create( tokenType, fromToken, text ); 196 dbg.CreateNode( node ); 197 return node; 198 } 199 200 public virtual object Create( int tokenType, string text ) 201 { 202 object node = adaptor.Create( tokenType, text ); 203 dbg.CreateNode( node ); 204 return node; 205 } 206 207 public object Create(IToken fromToken, string text) 208 { 209 object node = adaptor.Create(fromToken, text); 210 dbg.CreateNode(node); 211 return node; 212 } 213 214 public virtual int GetType( object t ) 215 { 216 return adaptor.GetType( t ); 217 } 218 219 public virtual void SetType( object t, int type ) 220 { 221 adaptor.SetType( t, type ); 222 } 223 224 public virtual string GetText( object t ) 225 { 226 return adaptor.GetText( t ); 227 } 228 229 public virtual void SetText( object t, string text ) 230 { 231 adaptor.SetText( t, text ); 232 } 233 234 public virtual IToken GetToken( object t ) 235 { 236 return adaptor.GetToken( t ); 237 } 238 239 public virtual void SetTokenBoundaries( object t, IToken startToken, IToken stopToken ) 240 { 241 adaptor.SetTokenBoundaries( t, startToken, stopToken ); 242 if ( t != null && startToken != null && stopToken != null ) 243 { 244 dbg.SetTokenBoundaries( 245 t, startToken.TokenIndex, 246 stopToken.TokenIndex ); 247 } 248 } 249 250 public virtual int GetTokenStartIndex( object t ) 251 { 252 return adaptor.GetTokenStartIndex( t ); 253 } 254 255 public virtual int GetTokenStopIndex( object t ) 256 { 257 return adaptor.GetTokenStopIndex( t ); 258 } 259 260 public virtual object GetChild( object t, int i ) 261 { 262 return adaptor.GetChild( t, i ); 263 } 264 265 public virtual void SetChild( object t, int i, object child ) 266 { 267 adaptor.SetChild( t, i, child ); 268 } 269 270 public virtual object DeleteChild( object t, int i ) 271 { 272 return DeleteChild( t, i ); 273 } 274 275 public virtual int GetChildCount( object t ) 276 { 277 return adaptor.GetChildCount( t ); 278 } 279 280 public virtual int GetUniqueID( object node ) 281 { 282 return adaptor.GetUniqueID( node ); 283 } 284 285 public virtual object GetParent( object t ) 286 { 287 return adaptor.GetParent( t ); 288 } 289 290 public virtual int GetChildIndex( object t ) 291 { 292 return adaptor.GetChildIndex( t ); 293 } 294 295 public virtual void SetParent( object t, object parent ) 296 { 297 adaptor.SetParent( t, parent ); 298 } 299 300 public virtual void SetChildIndex( object t, int index ) 301 { 302 adaptor.SetChildIndex( t, index ); 303 } 304 305 public virtual void ReplaceChildren( object parent, int startChildIndex, int stopChildIndex, object t ) 306 { 307 adaptor.ReplaceChildren( parent, startChildIndex, stopChildIndex, t ); 308 } 309 310 #region support 311 312 public virtual IDebugEventListener GetDebugListener() 313 { 314 return dbg; 315 } 316 317 public virtual void SetDebugListener( IDebugEventListener dbg ) 318 { 319 this.dbg = dbg; 320 } 321 322 public virtual ITreeAdaptor GetTreeAdaptor() 323 { 324 return adaptor; 325 } 326 327 #endregion 328 } 329} 330