258 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			258 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C#
		
	
	
	
| /*
 | |
|  * [The "BSD licence"]
 | |
|  * Copyright (c) 2005-2008 Terence Parr
 | |
|  * All rights reserved.
 | |
|  *
 | |
|  * Conversion to C#:
 | |
|  * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
 | |
|  * All rights reserved.
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without
 | |
|  * modification, are permitted provided that the following conditions
 | |
|  * are met:
 | |
|  * 1. Redistributions of source code must retain the above copyright
 | |
|  *    notice, this list of conditions and the following disclaimer.
 | |
|  * 2. Redistributions in binary form must reproduce the above copyright
 | |
|  *    notice, this list of conditions and the following disclaimer in the
 | |
|  *    documentation and/or other materials provided with the distribution.
 | |
|  * 3. The name of the author may not be used to endorse or promote products
 | |
|  *    derived from this software without specific prior written permission.
 | |
|  *
 | |
|  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 | |
|  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | |
|  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | |
|  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | |
|  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | |
|  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
|  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
|  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | |
|  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
|  */
 | |
| 
 | |
| namespace Antlr.Runtime.Debug {
 | |
|     using ITreeAdaptor = Antlr.Runtime.Tree.ITreeAdaptor;
 | |
| 
 | |
|     /** <summary>
 | |
|      *  A TreeAdaptor proxy that fires debugging events to a DebugEventListener
 | |
|      *  delegate and uses the TreeAdaptor delegate to do the actual work.  All
 | |
|      *  AST events are triggered by this adaptor; no code gen changes are needed
 | |
|      *  in generated rules.  Debugging events are triggered *after* invoking
 | |
|      *  tree adaptor routines.
 | |
|      *  </summary>
 | |
|      *
 | |
|      *  <remarks>
 | |
|      *  Trees created with actions in rewrite actions like "-> ^(ADD {foo} {bar})"
 | |
|      *  cannot be tracked as they might not use the adaptor to create foo, bar.
 | |
|      *  The debug listener has to deal with tree node IDs for which it did
 | |
|      *  not see a createNode event.  A single <unknown> node is sufficient even
 | |
|      *  if it represents a whole tree.
 | |
|      *  </remarks>
 | |
|      */
 | |
|     public class DebugTreeAdaptor : ITreeAdaptor {
 | |
|         protected IDebugEventListener dbg;
 | |
|         protected ITreeAdaptor adaptor;
 | |
| 
 | |
|         public DebugTreeAdaptor(IDebugEventListener dbg, ITreeAdaptor adaptor) {
 | |
|             this.dbg = dbg;
 | |
|             this.adaptor = adaptor;
 | |
|         }
 | |
| 
 | |
|         public virtual object Create(IToken payload) {
 | |
|             if (payload.TokenIndex < 0) {
 | |
|                 // could be token conjured up during error recovery
 | |
|                 return Create(payload.Type, payload.Text);
 | |
|             }
 | |
|             object node = adaptor.Create(payload);
 | |
|             dbg.CreateNode(node, payload);
 | |
|             return node;
 | |
|         }
 | |
| 
 | |
|         public virtual object ErrorNode(ITokenStream input, IToken start, IToken stop,
 | |
|                                 RecognitionException e) {
 | |
|             object node = adaptor.ErrorNode(input, start, stop, e);
 | |
|             if (node != null) {
 | |
|                 dbg.ErrorNode(node);
 | |
|             }
 | |
|             return node;
 | |
|         }
 | |
| 
 | |
|         public virtual object DupTree(object tree) {
 | |
|             object t = adaptor.DupTree(tree);
 | |
|             // walk the tree and emit create and add child events
 | |
|             // to simulate what dupTree has done. dupTree does not call this debug
 | |
|             // adapter so I must simulate.
 | |
|             SimulateTreeConstruction(t);
 | |
|             return t;
 | |
|         }
 | |
| 
 | |
|         /** <summary>^(A B C): emit create A, create B, add child, ...</summary> */
 | |
|         protected virtual void SimulateTreeConstruction(object t) {
 | |
|             dbg.CreateNode(t);
 | |
|             int n = adaptor.GetChildCount(t);
 | |
|             for (int i = 0; i < n; i++) {
 | |
|                 object child = adaptor.GetChild(t, i);
 | |
|                 SimulateTreeConstruction(child);
 | |
|                 dbg.AddChild(t, child);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public virtual object DupNode(object treeNode) {
 | |
|             object d = adaptor.DupNode(treeNode);
 | |
|             dbg.CreateNode(d);
 | |
|             return d;
 | |
|         }
 | |
| 
 | |
|         public virtual object Nil() {
 | |
|             object node = adaptor.Nil();
 | |
|             dbg.NilNode(node);
 | |
|             return node;
 | |
|         }
 | |
| 
 | |
|         public virtual bool IsNil(object tree) {
 | |
|             return adaptor.IsNil(tree);
 | |
|         }
 | |
| 
 | |
|         public virtual void AddChild(object t, object child) {
 | |
|             if (t == null || child == null) {
 | |
|                 return;
 | |
|             }
 | |
|             adaptor.AddChild(t, child);
 | |
|             dbg.AddChild(t, child);
 | |
|         }
 | |
| 
 | |
|         public virtual object BecomeRoot(object newRoot, object oldRoot) {
 | |
|             object n = adaptor.BecomeRoot(newRoot, oldRoot);
 | |
|             dbg.BecomeRoot(newRoot, oldRoot);
 | |
|             return n;
 | |
|         }
 | |
| 
 | |
|         public virtual object RulePostProcessing(object root) {
 | |
|             return adaptor.RulePostProcessing(root);
 | |
|         }
 | |
| 
 | |
|         public virtual void AddChild(object t, IToken child) {
 | |
|             object n = this.Create(child);
 | |
|             this.AddChild(t, n);
 | |
|         }
 | |
| 
 | |
|         public virtual object BecomeRoot(IToken newRoot, object oldRoot) {
 | |
|             object n = this.Create(newRoot);
 | |
|             adaptor.BecomeRoot(n, oldRoot);
 | |
|             dbg.BecomeRoot(newRoot, oldRoot);
 | |
|             return n;
 | |
|         }
 | |
| 
 | |
|         public virtual object Create(int tokenType, IToken fromToken) {
 | |
|             object node = adaptor.Create(tokenType, fromToken);
 | |
|             dbg.CreateNode(node);
 | |
|             return node;
 | |
|         }
 | |
| 
 | |
|         public virtual object Create(int tokenType, IToken fromToken, string text) {
 | |
|             object node = adaptor.Create(tokenType, fromToken, text);
 | |
|             dbg.CreateNode(node);
 | |
|             return node;
 | |
|         }
 | |
| 
 | |
|         public virtual object Create(int tokenType, string text) {
 | |
|             object node = adaptor.Create(tokenType, text);
 | |
|             dbg.CreateNode(node);
 | |
|             return node;
 | |
|         }
 | |
| 
 | |
|         public virtual int GetType(object t) {
 | |
|             return adaptor.GetType(t);
 | |
|         }
 | |
| 
 | |
|         public virtual void SetType(object t, int type) {
 | |
|             adaptor.SetType(t, type);
 | |
|         }
 | |
| 
 | |
|         public virtual string GetText(object t) {
 | |
|             return adaptor.GetText(t);
 | |
|         }
 | |
| 
 | |
|         public virtual void SetText(object t, string text) {
 | |
|             adaptor.SetText(t, text);
 | |
|         }
 | |
| 
 | |
|         public virtual IToken GetToken(object t) {
 | |
|             return adaptor.GetToken(t);
 | |
|         }
 | |
| 
 | |
|         public virtual void SetTokenBoundaries(object t, IToken startToken, IToken stopToken) {
 | |
|             adaptor.SetTokenBoundaries(t, startToken, stopToken);
 | |
|             if (t != null && startToken != null && stopToken != null) {
 | |
|                 dbg.SetTokenBoundaries(
 | |
|                     t, startToken.TokenIndex,
 | |
|                     stopToken.TokenIndex);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public virtual int GetTokenStartIndex(object t) {
 | |
|             return adaptor.GetTokenStartIndex(t);
 | |
|         }
 | |
| 
 | |
|         public virtual int GetTokenStopIndex(object t) {
 | |
|             return adaptor.GetTokenStopIndex(t);
 | |
|         }
 | |
| 
 | |
|         public virtual object GetChild(object t, int i) {
 | |
|             return adaptor.GetChild(t, i);
 | |
|         }
 | |
| 
 | |
|         public virtual void SetChild(object t, int i, object child) {
 | |
|             adaptor.SetChild(t, i, child);
 | |
|         }
 | |
| 
 | |
|         public virtual object DeleteChild(object t, int i) {
 | |
|             return DeleteChild(t, i);
 | |
|         }
 | |
| 
 | |
|         public virtual int GetChildCount(object t) {
 | |
|             return adaptor.GetChildCount(t);
 | |
|         }
 | |
| 
 | |
|         public virtual int GetUniqueID(object node) {
 | |
|             return adaptor.GetUniqueID(node);
 | |
|         }
 | |
| 
 | |
|         public virtual object GetParent(object t) {
 | |
|             return adaptor.GetParent(t);
 | |
|         }
 | |
| 
 | |
|         public virtual int GetChildIndex(object t) {
 | |
|             return adaptor.GetChildIndex(t);
 | |
|         }
 | |
| 
 | |
|         public virtual void SetParent(object t, object parent) {
 | |
|             adaptor.SetParent(t, parent);
 | |
|         }
 | |
| 
 | |
|         public virtual void SetChildIndex(object t, int index) {
 | |
|             adaptor.SetChildIndex(t, index);
 | |
|         }
 | |
| 
 | |
|         public virtual void ReplaceChildren(object parent, int startChildIndex, int stopChildIndex, object t) {
 | |
|             adaptor.ReplaceChildren(parent, startChildIndex, stopChildIndex, t);
 | |
|         }
 | |
| 
 | |
|         #region support
 | |
| 
 | |
|         public virtual IDebugEventListener GetDebugListener() {
 | |
|             return dbg;
 | |
|         }
 | |
| 
 | |
|         public virtual void SetDebugListener(IDebugEventListener dbg) {
 | |
|             this.dbg = dbg;
 | |
|         }
 | |
| 
 | |
|         public virtual ITreeAdaptor GetTreeAdaptor() {
 | |
|             return adaptor;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| }
 |