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.RecognitionException; 32 33 import java.util.List; 34 import java.util.ArrayList; 35 36 /** Broadcast debug events to multiple listeners. Lets you debug and still 37 * use the event mechanism to build parse trees etc... Not thread-safe. 38 * Don't add events in one thread while parser fires events in another. 39 * 40 * @see also DebugEventRepeater 41 */ 42 public class DebugEventHub implements DebugEventListener { 43 protected List listeners = new ArrayList(); 44 DebugEventHub(DebugEventListener listener)45 public DebugEventHub(DebugEventListener listener) { 46 listeners.add(listener); 47 } 48 DebugEventHub(DebugEventListener a, DebugEventListener b)49 public DebugEventHub(DebugEventListener a, DebugEventListener b) { 50 listeners.add(a); 51 listeners.add(b); 52 } 53 54 /** Add another listener to broadcast events too. Not thread-safe. 55 * Don't add events in one thread while parser fires events in another. 56 */ addListener(DebugEventListener listener)57 public void addListener(DebugEventListener listener) { 58 listeners.add(listener); 59 } 60 61 /* To avoid a mess like this: 62 public void enterRule(final String ruleName) { 63 broadcast(new Code(){ 64 public void exec(DebugEventListener listener) {listener.enterRule(ruleName);}} 65 ); 66 } 67 I am dup'ing the for-loop in each. Where are Java closures!? blech! 68 */ 69 enterRule(String grammarFileName, String ruleName)70 public void enterRule(String grammarFileName, String ruleName) { 71 for (int i = 0; i < listeners.size(); i++) { 72 DebugEventListener listener = (DebugEventListener)listeners.get(i); 73 listener.enterRule(grammarFileName,ruleName); 74 } 75 } 76 exitRule(String grammarFileName, String ruleName)77 public void exitRule(String grammarFileName, String ruleName) { 78 for (int i = 0; i < listeners.size(); i++) { 79 DebugEventListener listener = (DebugEventListener)listeners.get(i); 80 listener.exitRule(grammarFileName, ruleName); 81 } 82 } 83 enterAlt(int alt)84 public void enterAlt(int alt) { 85 for (int i = 0; i < listeners.size(); i++) { 86 DebugEventListener listener = (DebugEventListener)listeners.get(i); 87 listener.enterAlt(alt); 88 } 89 } 90 enterSubRule(int decisionNumber)91 public void enterSubRule(int decisionNumber) { 92 for (int i = 0; i < listeners.size(); i++) { 93 DebugEventListener listener = (DebugEventListener)listeners.get(i); 94 listener.enterSubRule(decisionNumber); 95 } 96 } 97 exitSubRule(int decisionNumber)98 public void exitSubRule(int decisionNumber) { 99 for (int i = 0; i < listeners.size(); i++) { 100 DebugEventListener listener = (DebugEventListener)listeners.get(i); 101 listener.exitSubRule(decisionNumber); 102 } 103 } 104 enterDecision(int decisionNumber, boolean couldBacktrack)105 public void enterDecision(int decisionNumber, boolean couldBacktrack) { 106 for (int i = 0; i < listeners.size(); i++) { 107 DebugEventListener listener = (DebugEventListener)listeners.get(i); 108 listener.enterDecision(decisionNumber, couldBacktrack); 109 } 110 } 111 exitDecision(int decisionNumber)112 public void exitDecision(int decisionNumber) { 113 for (int i = 0; i < listeners.size(); i++) { 114 DebugEventListener listener = (DebugEventListener)listeners.get(i); 115 listener.exitDecision(decisionNumber); 116 } 117 } 118 location(int line, int pos)119 public void location(int line, int pos) { 120 for (int i = 0; i < listeners.size(); i++) { 121 DebugEventListener listener = (DebugEventListener)listeners.get(i); 122 listener.location(line, pos); 123 } 124 } 125 consumeToken(Token token)126 public void consumeToken(Token token) { 127 for (int i = 0; i < listeners.size(); i++) { 128 DebugEventListener listener = (DebugEventListener)listeners.get(i); 129 listener.consumeToken(token); 130 } 131 } 132 consumeHiddenToken(Token token)133 public void consumeHiddenToken(Token token) { 134 for (int i = 0; i < listeners.size(); i++) { 135 DebugEventListener listener = (DebugEventListener)listeners.get(i); 136 listener.consumeHiddenToken(token); 137 } 138 } 139 LT(int index, Token t)140 public void LT(int index, Token t) { 141 for (int i = 0; i < listeners.size(); i++) { 142 DebugEventListener listener = (DebugEventListener)listeners.get(i); 143 listener.LT(index, t); 144 } 145 } 146 mark(int index)147 public void mark(int index) { 148 for (int i = 0; i < listeners.size(); i++) { 149 DebugEventListener listener = (DebugEventListener)listeners.get(i); 150 listener.mark(index); 151 } 152 } 153 rewind(int index)154 public void rewind(int index) { 155 for (int i = 0; i < listeners.size(); i++) { 156 DebugEventListener listener = (DebugEventListener)listeners.get(i); 157 listener.rewind(index); 158 } 159 } 160 rewind()161 public void rewind() { 162 for (int i = 0; i < listeners.size(); i++) { 163 DebugEventListener listener = (DebugEventListener)listeners.get(i); 164 listener.rewind(); 165 } 166 } 167 beginBacktrack(int level)168 public void beginBacktrack(int level) { 169 for (int i = 0; i < listeners.size(); i++) { 170 DebugEventListener listener = (DebugEventListener)listeners.get(i); 171 listener.beginBacktrack(level); 172 } 173 } 174 endBacktrack(int level, boolean successful)175 public void endBacktrack(int level, boolean successful) { 176 for (int i = 0; i < listeners.size(); i++) { 177 DebugEventListener listener = (DebugEventListener)listeners.get(i); 178 listener.endBacktrack(level, successful); 179 } 180 } 181 recognitionException(RecognitionException e)182 public void recognitionException(RecognitionException e) { 183 for (int i = 0; i < listeners.size(); i++) { 184 DebugEventListener listener = (DebugEventListener)listeners.get(i); 185 listener.recognitionException(e); 186 } 187 } 188 beginResync()189 public void beginResync() { 190 for (int i = 0; i < listeners.size(); i++) { 191 DebugEventListener listener = (DebugEventListener)listeners.get(i); 192 listener.beginResync(); 193 } 194 } 195 endResync()196 public void endResync() { 197 for (int i = 0; i < listeners.size(); i++) { 198 DebugEventListener listener = (DebugEventListener)listeners.get(i); 199 listener.endResync(); 200 } 201 } 202 semanticPredicate(boolean result, String predicate)203 public void semanticPredicate(boolean result, String predicate) { 204 for (int i = 0; i < listeners.size(); i++) { 205 DebugEventListener listener = (DebugEventListener)listeners.get(i); 206 listener.semanticPredicate(result, predicate); 207 } 208 } 209 commence()210 public void commence() { 211 for (int i = 0; i < listeners.size(); i++) { 212 DebugEventListener listener = (DebugEventListener)listeners.get(i); 213 listener.commence(); 214 } 215 } 216 terminate()217 public void terminate() { 218 for (int i = 0; i < listeners.size(); i++) { 219 DebugEventListener listener = (DebugEventListener)listeners.get(i); 220 listener.terminate(); 221 } 222 } 223 224 225 // Tree parsing stuff 226 consumeNode(Object t)227 public void consumeNode(Object t) { 228 for (int i = 0; i < listeners.size(); i++) { 229 DebugEventListener listener = (DebugEventListener)listeners.get(i); 230 listener.consumeNode(t); 231 } 232 } 233 LT(int index, Object t)234 public void LT(int index, Object t) { 235 for (int i = 0; i < listeners.size(); i++) { 236 DebugEventListener listener = (DebugEventListener)listeners.get(i); 237 listener.LT(index, t); 238 } 239 } 240 241 242 // AST Stuff 243 nilNode(Object t)244 public void nilNode(Object t) { 245 for (int i = 0; i < listeners.size(); i++) { 246 DebugEventListener listener = (DebugEventListener)listeners.get(i); 247 listener.nilNode(t); 248 } 249 } 250 errorNode(Object t)251 public void errorNode(Object t) { 252 for (int i = 0; i < listeners.size(); i++) { 253 DebugEventListener listener = (DebugEventListener)listeners.get(i); 254 listener.errorNode(t); 255 } 256 } 257 createNode(Object t)258 public void createNode(Object t) { 259 for (int i = 0; i < listeners.size(); i++) { 260 DebugEventListener listener = (DebugEventListener)listeners.get(i); 261 listener.createNode(t); 262 } 263 } 264 createNode(Object node, Token token)265 public void createNode(Object node, Token token) { 266 for (int i = 0; i < listeners.size(); i++) { 267 DebugEventListener listener = (DebugEventListener)listeners.get(i); 268 listener.createNode(node, token); 269 } 270 } 271 becomeRoot(Object newRoot, Object oldRoot)272 public void becomeRoot(Object newRoot, Object oldRoot) { 273 for (int i = 0; i < listeners.size(); i++) { 274 DebugEventListener listener = (DebugEventListener)listeners.get(i); 275 listener.becomeRoot(newRoot, oldRoot); 276 } 277 } 278 addChild(Object root, Object child)279 public void addChild(Object root, Object child) { 280 for (int i = 0; i < listeners.size(); i++) { 281 DebugEventListener listener = (DebugEventListener)listeners.get(i); 282 listener.addChild(root, child); 283 } 284 } 285 setTokenBoundaries(Object t, int tokenStartIndex, int tokenStopIndex)286 public void setTokenBoundaries(Object t, int tokenStartIndex, int tokenStopIndex) { 287 for (int i = 0; i < listeners.size(); i++) { 288 DebugEventListener listener = (DebugEventListener)listeners.get(i); 289 listener.setTokenBoundaries(t, tokenStartIndex, tokenStopIndex); 290 } 291 } 292 } 293