1 package antlr.debug; 2 3 import java.util.Vector; 4 import java.util.Hashtable; 5 import java.util.Enumeration; 6 import antlr.collections.impl.BitSet; 7 import antlr.RecognitionException; 8 9 10 /** A class to assist in firing parser events 11 * NOTE: I intentionally _did_not_ synchronize the event firing and 12 * add/remove listener methods. This is because the add/remove should 13 * _only_ be called by the parser at its start/end, and the _same_thread_ 14 * should be performing the parsing. This should help performance a tad... 15 */ 16 public class ParserEventSupport { 17 private Object source; 18 private Hashtable doneListeners; 19 private Vector matchListeners; 20 private Vector messageListeners; 21 private Vector tokenListeners; 22 private Vector traceListeners; 23 private Vector semPredListeners; 24 private Vector synPredListeners; 25 private Vector newLineListeners; 26 private ParserMatchEvent matchEvent; 27 private MessageEvent messageEvent; 28 private ParserTokenEvent tokenEvent; 29 private SemanticPredicateEvent semPredEvent; 30 private SyntacticPredicateEvent synPredEvent; 31 private TraceEvent traceEvent; 32 private NewLineEvent newLineEvent; 33 private ParserController controller; 34 protected static final int CONSUME=0; 35 protected static final int ENTER_RULE=1; 36 protected static final int EXIT_RULE=2; 37 protected static final int LA=3; 38 protected static final int MATCH=4; 39 protected static final int MATCH_NOT=5; 40 protected static final int MISMATCH=6; 41 protected static final int MISMATCH_NOT=7; 42 protected static final int REPORT_ERROR=8; 43 protected static final int REPORT_WARNING=9; 44 protected static final int SEMPRED=10; 45 protected static final int SYNPRED_FAILED=11; 46 protected static final int SYNPRED_STARTED=12; 47 protected static final int SYNPRED_SUCCEEDED=13; 48 protected static final int NEW_LINE=14; 49 protected static final int DONE_PARSING=15; 50 private int ruleDepth = 0; 51 52 ParserEventSupport(Object source)53 public ParserEventSupport(Object source) { 54 matchEvent = new ParserMatchEvent(source); 55 messageEvent = new MessageEvent(source); 56 tokenEvent = new ParserTokenEvent(source); 57 traceEvent = new TraceEvent(source); 58 semPredEvent = new SemanticPredicateEvent(source); 59 synPredEvent = new SyntacticPredicateEvent(source); 60 newLineEvent = new NewLineEvent(source); 61 this.source = source; 62 } addDoneListener(ListenerBase l)63 public void addDoneListener(ListenerBase l) { 64 if (doneListeners == null) doneListeners = new Hashtable(); 65 Integer i = (Integer)doneListeners.get(l); 66 int val; 67 if (i != null) 68 val = i.intValue() + 1; 69 else 70 val = 1; 71 doneListeners.put(l, new Integer(val)); 72 } addMessageListener(MessageListener l)73 public void addMessageListener(MessageListener l) { 74 if (messageListeners == null) messageListeners = new Vector(); 75 messageListeners.addElement(l); 76 addDoneListener(l); 77 } addNewLineListener(NewLineListener l)78 public void addNewLineListener(NewLineListener l) { 79 if (newLineListeners == null) newLineListeners = new Vector(); 80 newLineListeners.addElement(l); 81 addDoneListener(l); 82 } addParserListener(ParserListener l)83 public void addParserListener(ParserListener l) { 84 if (l instanceof ParserController) { 85 ((ParserController)l).setParserEventSupport(this); 86 controller = (ParserController)l; 87 } 88 addParserMatchListener(l); 89 addParserTokenListener(l); 90 91 addMessageListener(l); 92 addTraceListener(l); 93 addSemanticPredicateListener(l); 94 addSyntacticPredicateListener(l); 95 } addParserMatchListener(ParserMatchListener l)96 public void addParserMatchListener(ParserMatchListener l) { 97 if (matchListeners == null) matchListeners = new Vector(); 98 matchListeners.addElement(l); 99 addDoneListener(l); 100 } addParserTokenListener(ParserTokenListener l)101 public void addParserTokenListener(ParserTokenListener l) { 102 if (tokenListeners == null) tokenListeners = new Vector(); 103 tokenListeners.addElement(l); 104 addDoneListener(l); 105 } addSemanticPredicateListener(SemanticPredicateListener l)106 public void addSemanticPredicateListener(SemanticPredicateListener l) { 107 if (semPredListeners == null) semPredListeners = new Vector(); 108 semPredListeners.addElement(l); 109 addDoneListener(l); 110 } addSyntacticPredicateListener(SyntacticPredicateListener l)111 public void addSyntacticPredicateListener(SyntacticPredicateListener l) { 112 if (synPredListeners == null) synPredListeners = new Vector(); 113 synPredListeners.addElement(l); 114 addDoneListener(l); 115 } addTraceListener(TraceListener l)116 public void addTraceListener(TraceListener l) { 117 if (traceListeners == null) traceListeners = new Vector(); 118 traceListeners.addElement(l); 119 addDoneListener(l); 120 } fireConsume(int value)121 public void fireConsume(int value) { 122 tokenEvent.setValues(ParserTokenEvent.CONSUME, 1, value); 123 fireEvents(CONSUME, tokenListeners); 124 } fireDoneParsing()125 public void fireDoneParsing() { 126 traceEvent.setValues(TraceEvent.DONE_PARSING, 0,0,0); 127 128 Hashtable targets=null; 129 // Hashtable targets=doneListeners; 130 ListenerBase l=null; 131 132 synchronized (this) { 133 if (doneListeners == null) return; 134 targets = (Hashtable)doneListeners.clone(); 135 } 136 137 if (targets != null) { 138 Enumeration e = targets.keys(); 139 while(e.hasMoreElements()) { 140 l = (ListenerBase)e.nextElement(); 141 fireEvent(DONE_PARSING, l); 142 } 143 } 144 if (controller != null) 145 controller.checkBreak(); 146 } fireEnterRule(int ruleNum, int guessing, int data)147 public void fireEnterRule(int ruleNum, int guessing, int data) { 148 ruleDepth++; 149 traceEvent.setValues(TraceEvent.ENTER, ruleNum, guessing, data); 150 fireEvents(ENTER_RULE, traceListeners); 151 } fireEvent(int type, ListenerBase l)152 public void fireEvent(int type, ListenerBase l) { 153 switch(type) { 154 case CONSUME: ((ParserTokenListener)l).parserConsume(tokenEvent); break; 155 case LA: ((ParserTokenListener)l).parserLA(tokenEvent); break; 156 157 case ENTER_RULE: ((TraceListener)l).enterRule(traceEvent); break; 158 case EXIT_RULE: ((TraceListener)l).exitRule(traceEvent); break; 159 160 case MATCH: ((ParserMatchListener)l).parserMatch(matchEvent); break; 161 case MATCH_NOT: ((ParserMatchListener)l).parserMatchNot(matchEvent); break; 162 case MISMATCH: ((ParserMatchListener)l).parserMismatch(matchEvent); break; 163 case MISMATCH_NOT: ((ParserMatchListener)l).parserMismatchNot(matchEvent); break; 164 165 case SEMPRED: ((SemanticPredicateListener)l).semanticPredicateEvaluated(semPredEvent); break; 166 167 case SYNPRED_STARTED: ((SyntacticPredicateListener)l).syntacticPredicateStarted(synPredEvent); break; 168 case SYNPRED_FAILED: ((SyntacticPredicateListener)l).syntacticPredicateFailed(synPredEvent); break; 169 case SYNPRED_SUCCEEDED: ((SyntacticPredicateListener)l).syntacticPredicateSucceeded(synPredEvent); break; 170 171 case REPORT_ERROR: ((MessageListener)l).reportError(messageEvent); break; 172 case REPORT_WARNING: ((MessageListener)l).reportWarning(messageEvent); break; 173 174 case DONE_PARSING: l.doneParsing(traceEvent); break; 175 case NEW_LINE: ((NewLineListener)l).hitNewLine(newLineEvent); break; 176 177 default: 178 throw new IllegalArgumentException("bad type "+type+" for fireEvent()"); 179 } 180 } fireEvents(int type, Vector listeners)181 public void fireEvents(int type, Vector listeners) { 182 ListenerBase l=null; 183 184 if (listeners != null) 185 for (int i = 0; i < listeners.size(); i++) { 186 l = (ListenerBase)listeners.elementAt(i); 187 fireEvent(type, l); 188 } 189 if (controller != null) 190 controller.checkBreak(); 191 } fireExitRule(int ruleNum, int guessing, int data)192 public void fireExitRule(int ruleNum, int guessing, int data) { 193 traceEvent.setValues(TraceEvent.EXIT, ruleNum, guessing, data); 194 fireEvents(EXIT_RULE, traceListeners); 195 ruleDepth--; 196 if (ruleDepth == 0) 197 fireDoneParsing(); 198 } fireLA(int k, int la)199 public void fireLA(int k, int la) { 200 tokenEvent.setValues(ParserTokenEvent.LA, k, la); 201 fireEvents(LA, tokenListeners); 202 } fireMatch(char c, int guessing)203 public void fireMatch(char c, int guessing) { 204 matchEvent.setValues(ParserMatchEvent.CHAR, c, new Character(c), null, guessing, false, true); 205 fireEvents(MATCH, matchListeners); 206 } fireMatch(char value, BitSet b, int guessing)207 public void fireMatch(char value, BitSet b, int guessing) { 208 matchEvent.setValues(ParserMatchEvent.CHAR_BITSET, value, b, null, guessing, false, true); 209 fireEvents(MATCH, matchListeners); 210 } fireMatch(char value, String target, int guessing)211 public void fireMatch(char value, String target, int guessing) { 212 matchEvent.setValues(ParserMatchEvent.CHAR_RANGE, value, target, null, guessing, false, true); 213 fireEvents(MATCH, matchListeners); 214 } fireMatch(int value, BitSet b, String text, int guessing)215 public void fireMatch(int value, BitSet b, String text, int guessing) { 216 matchEvent.setValues(ParserMatchEvent.BITSET, value, b, text, guessing, false, true); 217 fireEvents(MATCH, matchListeners); 218 } fireMatch(int n, String text, int guessing)219 public void fireMatch(int n, String text, int guessing) { 220 matchEvent.setValues(ParserMatchEvent.TOKEN, n, new Integer(n), text, guessing, false, true); 221 fireEvents(MATCH, matchListeners); 222 } fireMatch(String s, int guessing)223 public void fireMatch(String s, int guessing) { 224 matchEvent.setValues(ParserMatchEvent.STRING, 0, s, null, guessing, false, true); 225 fireEvents(MATCH, matchListeners); 226 } fireMatchNot(char value, char n, int guessing)227 public void fireMatchNot(char value, char n, int guessing) { 228 matchEvent.setValues(ParserMatchEvent.CHAR, value, new Character(n), null, guessing, true, true); 229 fireEvents(MATCH_NOT, matchListeners); 230 } fireMatchNot(int value, int n, String text, int guessing)231 public void fireMatchNot(int value, int n, String text, int guessing) { 232 matchEvent.setValues(ParserMatchEvent.TOKEN, value, new Integer(n), text, guessing, true, true); 233 fireEvents(MATCH_NOT, matchListeners); 234 } fireMismatch(char value, char n, int guessing)235 public void fireMismatch(char value, char n, int guessing) { 236 matchEvent.setValues(ParserMatchEvent.CHAR, value, new Character(n), null, guessing, false, false); 237 fireEvents(MISMATCH, matchListeners); 238 } fireMismatch(char value, BitSet b, int guessing)239 public void fireMismatch(char value, BitSet b, int guessing) { 240 matchEvent.setValues(ParserMatchEvent.CHAR_BITSET, value, b, null, guessing, false, true); 241 fireEvents(MISMATCH, matchListeners); 242 } fireMismatch(char value, String target, int guessing)243 public void fireMismatch(char value, String target, int guessing) { 244 matchEvent.setValues(ParserMatchEvent.CHAR_RANGE, value, target, null, guessing, false, true); 245 fireEvents(MISMATCH, matchListeners); 246 } fireMismatch(int value, int n, String text, int guessing)247 public void fireMismatch(int value, int n, String text, int guessing) { 248 matchEvent.setValues(ParserMatchEvent.TOKEN, value, new Integer(n), text, guessing, false, false); 249 fireEvents(MISMATCH, matchListeners); 250 } fireMismatch(int value, BitSet b, String text, int guessing)251 public void fireMismatch(int value, BitSet b, String text, int guessing) { 252 matchEvent.setValues(ParserMatchEvent.BITSET, value, b, text, guessing, false, true); 253 fireEvents(MISMATCH, matchListeners); 254 } fireMismatch(String value, String text, int guessing)255 public void fireMismatch(String value, String text, int guessing) { 256 matchEvent.setValues(ParserMatchEvent.STRING, 0, text, value, guessing, false, true); 257 fireEvents(MISMATCH, matchListeners); 258 } fireMismatchNot(char value, char c, int guessing)259 public void fireMismatchNot(char value, char c, int guessing) { 260 matchEvent.setValues(ParserMatchEvent.CHAR, value, new Character(c), null, guessing, true, true); 261 fireEvents(MISMATCH_NOT, matchListeners); 262 } fireMismatchNot(int value, int n, String text, int guessing)263 public void fireMismatchNot(int value, int n, String text, int guessing) { 264 matchEvent.setValues(ParserMatchEvent.TOKEN, value, new Integer(n), text, guessing, true, true); 265 fireEvents(MISMATCH_NOT, matchListeners); 266 } fireNewLine(int line)267 public void fireNewLine(int line) { 268 newLineEvent.setValues(line); 269 fireEvents(NEW_LINE, newLineListeners); 270 } fireReportError(Exception e)271 public void fireReportError(Exception e) { 272 messageEvent.setValues(MessageEvent.ERROR, e.toString()); 273 fireEvents(REPORT_ERROR, messageListeners); 274 } fireReportError(String s)275 public void fireReportError(String s) { 276 messageEvent.setValues(MessageEvent.ERROR, s); 277 fireEvents(REPORT_ERROR, messageListeners); 278 } fireReportWarning(String s)279 public void fireReportWarning(String s) { 280 messageEvent.setValues(MessageEvent.WARNING, s); 281 fireEvents(REPORT_WARNING, messageListeners); 282 } fireSemanticPredicateEvaluated(int type, int condition, boolean result, int guessing)283 public boolean fireSemanticPredicateEvaluated(int type, int condition, boolean result, int guessing) { 284 semPredEvent.setValues(type, condition, result, guessing); 285 fireEvents(SEMPRED, semPredListeners); 286 return result; 287 } fireSyntacticPredicateFailed(int guessing)288 public void fireSyntacticPredicateFailed(int guessing) { 289 synPredEvent.setValues(0, guessing); 290 fireEvents(SYNPRED_FAILED, synPredListeners); 291 } fireSyntacticPredicateStarted(int guessing)292 public void fireSyntacticPredicateStarted(int guessing) { 293 synPredEvent.setValues(0, guessing); 294 fireEvents(SYNPRED_STARTED, synPredListeners); 295 } fireSyntacticPredicateSucceeded(int guessing)296 public void fireSyntacticPredicateSucceeded(int guessing) { 297 synPredEvent.setValues(0, guessing); 298 fireEvents(SYNPRED_SUCCEEDED, synPredListeners); 299 } refresh(Vector listeners)300 protected void refresh(Vector listeners) { 301 Vector v; 302 synchronized (listeners) { 303 v = (Vector)listeners.clone(); 304 } 305 if (v != null) 306 for (int i = 0; i < v.size(); i++) 307 ((ListenerBase)v.elementAt(i)).refresh(); 308 } refreshListeners()309 public void refreshListeners() { 310 refresh(matchListeners); 311 refresh(messageListeners); 312 refresh(tokenListeners); 313 refresh(traceListeners); 314 refresh(semPredListeners); 315 refresh(synPredListeners); 316 } removeDoneListener(ListenerBase l)317 public void removeDoneListener(ListenerBase l) { 318 if (doneListeners == null) return; 319 Integer i = (Integer)doneListeners.get(l); 320 int val=0; 321 if (i != null) 322 val = i.intValue() - 1; 323 324 if (val == 0) 325 doneListeners.remove(l); 326 else 327 doneListeners.put(l, new Integer(val)); 328 } removeMessageListener(MessageListener l)329 public void removeMessageListener(MessageListener l) { 330 if (messageListeners != null) 331 messageListeners.removeElement(l); 332 removeDoneListener(l); 333 } removeNewLineListener(NewLineListener l)334 public void removeNewLineListener(NewLineListener l) { 335 if (newLineListeners != null) 336 newLineListeners.removeElement(l); 337 removeDoneListener(l); 338 } removeParserListener(ParserListener l)339 public void removeParserListener(ParserListener l) { 340 removeParserMatchListener(l); 341 removeMessageListener(l); 342 removeParserTokenListener(l); 343 removeTraceListener(l); 344 removeSemanticPredicateListener(l); 345 removeSyntacticPredicateListener(l); 346 } removeParserMatchListener(ParserMatchListener l)347 public void removeParserMatchListener(ParserMatchListener l) { 348 if (matchListeners != null) 349 matchListeners.removeElement(l); 350 removeDoneListener(l); 351 } removeParserTokenListener(ParserTokenListener l)352 public void removeParserTokenListener(ParserTokenListener l) { 353 if (tokenListeners != null) 354 tokenListeners.removeElement(l); 355 removeDoneListener(l); 356 } removeSemanticPredicateListener(SemanticPredicateListener l)357 public void removeSemanticPredicateListener(SemanticPredicateListener l) { 358 if (semPredListeners != null) 359 semPredListeners.removeElement(l); 360 removeDoneListener(l); 361 } removeSyntacticPredicateListener(SyntacticPredicateListener l)362 public void removeSyntacticPredicateListener(SyntacticPredicateListener l) { 363 if (synPredListeners != null) 364 synPredListeners.removeElement(l); 365 removeDoneListener(l); 366 } removeTraceListener(TraceListener l)367 public void removeTraceListener(TraceListener l) { 368 if (traceListeners != null) 369 traceListeners.removeElement(l); 370 removeDoneListener(l); 371 } 372 } 373