1 /* 2 * [The "BSD licence"] 3 * Copyright (c) 2005-2008 Terence Parr 4 * All rights reserved. 5 * 6 * Conversion to C#: 7 * Copyright (c) 2008-2009 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 33 namespace Antlr.Runtime.Debug { 34 using System.Collections.Generic; 35 36 /** <summary> 37 * Broadcast debug events to multiple listeners. Lets you debug and still 38 * use the event mechanism to build parse trees etc... Not thread-safe. 39 * Don't add events in one thread while parser fires events in another. 40 * </summary> 41 * 42 * <seealso cref="DebugEventRepeater"/> 43 */ 44 public class DebugEventHub : IDebugEventListener { 45 List<IDebugEventListener> _listeners = new List<IDebugEventListener>(); 46 47 public DebugEventHub(params IDebugEventListener[] listeners) { 48 _listeners = new List<IDebugEventListener>(listeners); 49 } 50 51 public virtual void Initialize() { 52 } 53 54 /** <summary> 55 * Add another listener to broadcast events too. Not thread-safe. 56 * Don't add events in one thread while parser fires events in another. 57 * </summary> 58 */ 59 public virtual void AddListener(IDebugEventListener listener) { 60 _listeners.Add(listener); 61 } 62 63 /* To avoid a mess like this: 64 public void enterRule(final String ruleName) { 65 broadcast(new Code(){ 66 public void exec(DebugEventListener listener) {listener.enterRule(ruleName);}} 67 ); 68 } 69 I am dup'ing the for-loop in each. Where are Java closures!? blech! 70 */ 71 72 public virtual void EnterRule(string grammarFileName, string ruleName) { 73 for (int i = 0; i < _listeners.Count; i++) { 74 IDebugEventListener listener = _listeners[i]; 75 listener.EnterRule(grammarFileName, ruleName); 76 } 77 } 78 79 public virtual void ExitRule(string grammarFileName, string ruleName) { 80 for (int i = 0; i < _listeners.Count; i++) { 81 IDebugEventListener listener = _listeners[i]; 82 listener.ExitRule(grammarFileName, ruleName); 83 } 84 } 85 86 public virtual void EnterAlt(int alt) { 87 for (int i = 0; i < _listeners.Count; i++) { 88 IDebugEventListener listener = _listeners[i]; 89 listener.EnterAlt(alt); 90 } 91 } 92 93 public virtual void EnterSubRule(int decisionNumber) { 94 for (int i = 0; i < _listeners.Count; i++) { 95 IDebugEventListener listener = _listeners[i]; 96 listener.EnterSubRule(decisionNumber); 97 } 98 } 99 100 public virtual void ExitSubRule(int decisionNumber) { 101 for (int i = 0; i < _listeners.Count; i++) { 102 IDebugEventListener listener = _listeners[i]; 103 listener.ExitSubRule(decisionNumber); 104 } 105 } 106 107 public virtual void EnterDecision(int decisionNumber, bool couldBacktrack) { 108 for (int i = 0; i < _listeners.Count; i++) { 109 IDebugEventListener listener = _listeners[i]; 110 listener.EnterDecision(decisionNumber, couldBacktrack); 111 } 112 } 113 114 public virtual void ExitDecision(int decisionNumber) { 115 for (int i = 0; i < _listeners.Count; i++) { 116 IDebugEventListener listener = _listeners[i]; 117 listener.ExitDecision(decisionNumber); 118 } 119 } 120 121 public virtual void Location(int line, int pos) { 122 for (int i = 0; i < _listeners.Count; i++) { 123 IDebugEventListener listener = _listeners[i]; 124 listener.Location(line, pos); 125 } 126 } 127 128 public virtual void ConsumeToken(IToken token) { 129 for (int i = 0; i < _listeners.Count; i++) { 130 IDebugEventListener listener = _listeners[i]; 131 listener.ConsumeToken(token); 132 } 133 } 134 135 public virtual void ConsumeHiddenToken(IToken token) { 136 for (int i = 0; i < _listeners.Count; i++) { 137 IDebugEventListener listener = _listeners[i]; 138 listener.ConsumeHiddenToken(token); 139 } 140 } 141 142 public virtual void LT(int index, IToken t) { 143 for (int i = 0; i < _listeners.Count; i++) { 144 IDebugEventListener listener = _listeners[i]; 145 listener.LT(index, t); 146 } 147 } 148 149 public virtual void Mark(int index) { 150 for (int i = 0; i < _listeners.Count; i++) { 151 IDebugEventListener listener = _listeners[i]; 152 listener.Mark(index); 153 } 154 } 155 156 public virtual void Rewind(int index) { 157 for (int i = 0; i < _listeners.Count; i++) { 158 IDebugEventListener listener = _listeners[i]; 159 listener.Rewind(index); 160 } 161 } 162 163 public virtual void Rewind() { 164 for (int i = 0; i < _listeners.Count; i++) { 165 IDebugEventListener listener = _listeners[i]; 166 listener.Rewind(); 167 } 168 } 169 170 public virtual void BeginBacktrack(int level) { 171 for (int i = 0; i < _listeners.Count; i++) { 172 IDebugEventListener listener = _listeners[i]; 173 listener.BeginBacktrack(level); 174 } 175 } 176 177 public virtual void EndBacktrack(int level, bool successful) { 178 for (int i = 0; i < _listeners.Count; i++) { 179 IDebugEventListener listener = _listeners[i]; 180 listener.EndBacktrack(level, successful); 181 } 182 } 183 184 public virtual void RecognitionException(RecognitionException e) { 185 for (int i = 0; i < _listeners.Count; i++) { 186 IDebugEventListener listener = _listeners[i]; 187 listener.RecognitionException(e); 188 } 189 } 190 191 public virtual void BeginResync() { 192 for (int i = 0; i < _listeners.Count; i++) { 193 IDebugEventListener listener = _listeners[i]; 194 listener.BeginResync(); 195 } 196 } 197 198 public virtual void EndResync() { 199 for (int i = 0; i < _listeners.Count; i++) { 200 IDebugEventListener listener = _listeners[i]; 201 listener.EndResync(); 202 } 203 } 204 205 public virtual void SemanticPredicate(bool result, string predicate) { 206 for (int i = 0; i < _listeners.Count; i++) { 207 IDebugEventListener listener = _listeners[i]; 208 listener.SemanticPredicate(result, predicate); 209 } 210 } 211 212 public virtual void Commence() { 213 for (int i = 0; i < _listeners.Count; i++) { 214 IDebugEventListener listener = _listeners[i]; 215 listener.Commence(); 216 } 217 } 218 219 public virtual void Terminate() { 220 for (int i = 0; i < _listeners.Count; i++) { 221 IDebugEventListener listener = _listeners[i]; 222 listener.Terminate(); 223 } 224 } 225 226 227 #region Tree parsing stuff 228 229 public virtual void ConsumeNode(object t) { 230 for (int i = 0; i < _listeners.Count; i++) { 231 IDebugEventListener listener = _listeners[i]; 232 listener.ConsumeNode(t); 233 } 234 } 235 236 public virtual void LT(int index, object t) { 237 for (int i = 0; i < _listeners.Count; i++) { 238 IDebugEventListener listener = _listeners[i]; 239 listener.LT(index, t); 240 } 241 } 242 243 #endregion 244 245 246 #region AST Stuff 247 248 public virtual void NilNode(object t) { 249 for (int i = 0; i < _listeners.Count; i++) { 250 IDebugEventListener listener = _listeners[i]; 251 listener.NilNode(t); 252 } 253 } 254 255 public virtual void ErrorNode(object t) { 256 for (int i = 0; i < _listeners.Count; i++) { 257 IDebugEventListener listener = _listeners[i]; 258 listener.ErrorNode(t); 259 } 260 } 261 262 public virtual void CreateNode(object t) { 263 for (int i = 0; i < _listeners.Count; i++) { 264 IDebugEventListener listener = _listeners[i]; 265 listener.CreateNode(t); 266 } 267 } 268 269 public virtual void CreateNode(object node, IToken token) { 270 for (int i = 0; i < _listeners.Count; i++) { 271 IDebugEventListener listener = _listeners[i]; 272 listener.CreateNode(node, token); 273 } 274 } 275 276 public virtual void BecomeRoot(object newRoot, object oldRoot) { 277 for (int i = 0; i < _listeners.Count; i++) { 278 IDebugEventListener listener = _listeners[i]; 279 listener.BecomeRoot(newRoot, oldRoot); 280 } 281 } 282 283 public virtual void AddChild(object root, object child) { 284 for (int i = 0; i < _listeners.Count; i++) { 285 IDebugEventListener listener = _listeners[i]; 286 listener.AddChild(root, child); 287 } 288 } 289 290 public virtual void SetTokenBoundaries(object t, int tokenStartIndex, int tokenStopIndex) { 291 for (int i = 0; i < _listeners.Count; i++) { 292 IDebugEventListener listener = _listeners[i]; 293 listener.SetTokenBoundaries(t, tokenStartIndex, tokenStopIndex); 294 } 295 } 296 297 #endregion 298 } 299 } 300