1 /** 2 * \file 3 * The definition of all debugging events that a recognizer can trigger. 4 * 5 * \remark 6 * From the java implementation by Terence Parr... 7 * I did not create a separate AST debugging interface as it would create 8 * lots of extra classes and DebugParser has a dbg var defined, which makes 9 * it hard to change to ASTDebugEventListener. I looked hard at this issue 10 * and it is easier to understand as one monolithic event interface for all 11 * possible events. Hopefully, adding ST debugging stuff won't be bad. Leave 12 * for future. 4/26/2006. 13 */ 14 15 #ifndef ANTLR3_DEBUG_EVENT_LISTENER_H 16 #define ANTLR3_DEBUG_EVENT_LISTENER_H 17 18 // [The "BSD licence"] 19 // Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC 20 // http://www.temporal-wave.com 21 // http://www.linkedin.com/in/jimidle 22 // 23 // All rights reserved. 24 // 25 // Redistribution and use in source and binary forms, with or without 26 // modification, are permitted provided that the following conditions 27 // are met: 28 // 1. Redistributions of source code must retain the above copyright 29 // notice, this list of conditions and the following disclaimer. 30 // 2. Redistributions in binary form must reproduce the above copyright 31 // notice, this list of conditions and the following disclaimer in the 32 // documentation and/or other materials provided with the distribution. 33 // 3. The name of the author may not be used to endorse or promote products 34 // derived from this software without specific prior written permission. 35 // 36 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 37 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 38 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 39 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 40 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 45 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 47 #include <antlr3defs.h> 48 #include <antlr3basetree.h> 49 #include <antlr3commontoken.h> 50 51 52 /// Default debugging port 53 /// 54 #define DEFAULT_DEBUGGER_PORT 0xBFCC; 55 56 #ifdef __cplusplus 57 extern "C" { 58 #endif 59 60 /** The ANTLR3 debugging interface for communicating with ANLTR Works. Function comments 61 * mostly taken from the Java version. 62 */ 63 typedef struct ANTLR3_DEBUG_EVENT_LISTENER_struct 64 { 65 /// The port number which the debug listener should listen on for a connection 66 /// 67 ANTLR3_UINT32 port; 68 69 /// The socket structure we receive after a successful accept on the serverSocket 70 /// 71 SOCKET socket; 72 73 /** The version of the debugging protocol supported by the providing 74 * instance of the debug event listener. 75 */ 76 int protocol_version; 77 78 /// The name of the grammar file that we are debugging 79 /// 80 pANTLR3_STRING grammarFileName; 81 82 /// Indicates whether we have already connected or not 83 /// 84 ANTLR3_BOOLEAN initialized; 85 86 /// Used to serialize the values of any particular token we need to 87 /// send back to the debugger. 88 /// 89 pANTLR3_STRING tokenString; 90 91 92 /// Allows the debug event system to access the adapter in use 93 /// by the recognizer, if this is a tree parser of some sort. 94 /// 95 pANTLR3_BASE_TREE_ADAPTOR adaptor; 96 97 /// Wait for a connection from the debugger and initiate the 98 /// debugging session. 99 /// 100 ANTLR3_BOOLEAN (*handshake) (pANTLR3_DEBUG_EVENT_LISTENER delboy); 101 102 /** The parser has just entered a rule. No decision has been made about 103 * which alt is predicted. This is fired AFTER init actions have been 104 * executed. Attributes are defined and available etc... 105 */ 106 void (*enterRule) (pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * grammarFileName, const char * ruleName); 107 108 /** Because rules can have lots of alternatives, it is very useful to 109 * know which alt you are entering. This is 1..n for n alts. 110 */ 111 void (*enterAlt) (pANTLR3_DEBUG_EVENT_LISTENER delboy, int alt); 112 113 /** This is the last thing executed before leaving a rule. It is 114 * executed even if an exception is thrown. This is triggered after 115 * error reporting and recovery have occurred (unless the exception is 116 * not caught in this rule). This implies an "exitAlt" event. 117 */ 118 void (*exitRule) (pANTLR3_DEBUG_EVENT_LISTENER delboy, const char * grammarFileName, const char * ruleName); 119 120 /** Track entry into any (...) subrule other EBNF construct 121 */ 122 void (*enterSubRule) (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber); 123 124 void (*exitSubRule) (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber); 125 126 /** Every decision, fixed k or arbitrary, has an enter/exit event 127 * so that a GUI can easily track what LT/consume events are 128 * associated with prediction. You will see a single enter/exit 129 * subrule but multiple enter/exit decision events, one for each 130 * loop iteration. 131 */ 132 void (*enterDecision) (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber); 133 134 void (*exitDecision) (pANTLR3_DEBUG_EVENT_LISTENER delboy, int decisionNumber); 135 136 /** An input token was consumed; matched by any kind of element. 137 * Trigger after the token was matched by things like match(), matchAny(). 138 */ 139 void (*consumeToken) (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t); 140 141 /** An off-channel input token was consumed. 142 * Trigger after the token was matched by things like match(), matchAny(). 143 * (unless of course the hidden token is first stuff in the input stream). 144 */ 145 void (*consumeHiddenToken) (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_COMMON_TOKEN t); 146 147 /** Somebody (anybody) looked ahead. Note that this actually gets 148 * triggered by both LA and LT calls. The debugger will want to know 149 * which Token object was examined. Like consumeToken, this indicates 150 * what token was seen at that depth. A remote debugger cannot look 151 * ahead into a file it doesn't have so LT events must pass the token 152 * even if the info is redundant. 153 */ 154 void (*LT) (pANTLR3_DEBUG_EVENT_LISTENER delboy, int i, pANTLR3_COMMON_TOKEN t); 155 156 /** The parser is going to look arbitrarily ahead; mark this location, 157 * the token stream's marker is sent in case you need it. 158 */ 159 void (*mark) (pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_MARKER marker); 160 161 /** After an arbitrarily long lookahead as with a cyclic DFA (or with 162 * any backtrack), this informs the debugger that stream should be 163 * rewound to the position associated with marker. 164 */ 165 void (*rewind) (pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_MARKER marker); 166 167 /** Rewind to the input position of the last marker. 168 * Used currently only after a cyclic DFA and just 169 * before starting a sem/syn predicate to get the 170 * input position back to the start of the decision. 171 * Do not "pop" the marker off the state. mark(i) 172 * and rewind(i) should balance still. 173 */ 174 void (*rewindLast) (pANTLR3_DEBUG_EVENT_LISTENER delboy); 175 176 void (*beginBacktrack) (pANTLR3_DEBUG_EVENT_LISTENER delboy, int level); 177 178 void (*endBacktrack) (pANTLR3_DEBUG_EVENT_LISTENER delboy, int level, ANTLR3_BOOLEAN successful); 179 180 /** To watch a parser move through the grammar, the parser needs to 181 * inform the debugger what line/charPos it is passing in the grammar. 182 * For now, this does not know how to switch from one grammar to the 183 * other and back for island grammars etc... 184 * 185 * This should also allow breakpoints because the debugger can stop 186 * the parser whenever it hits this line/pos. 187 */ 188 void (*location) (pANTLR3_DEBUG_EVENT_LISTENER delboy, int line, int pos); 189 190 /** A recognition exception occurred such as NoViableAltException. I made 191 * this a generic event so that I can alter the exception hierarchy later 192 * without having to alter all the debug objects. 193 * 194 * Upon error, the stack of enter rule/subrule must be properly unwound. 195 * If no viable alt occurs it is within an enter/exit decision, which 196 * also must be rewound. Even the rewind for each mark must be unwound. 197 * In the Java target this is pretty easy using try/finally, if a bit 198 * ugly in the generated code. The rewind is generated in DFA.predict() 199 * actually so no code needs to be generated for that. For languages 200 * w/o this "finally" feature (C++?), the target implementor will have 201 * to build an event stack or something. 202 * 203 * Across a socket for remote debugging, only the RecognitionException 204 * data fields are transmitted. The token object or whatever that 205 * caused the problem was the last object referenced by LT. The 206 * immediately preceding LT event should hold the unexpected Token or 207 * char. 208 * 209 * Here is a sample event trace for grammar: 210 * 211 * b : C ({;}A|B) // {;} is there to prevent A|B becoming a set 212 * | D 213 * ; 214 * 215 * The sequence for this rule (with no viable alt in the subrule) for 216 * input 'c c' (there are 3 tokens) is: 217 * 218 * commence 219 * LT(1) 220 * enterRule b 221 * location 7 1 222 * enter decision 3 223 * LT(1) 224 * exit decision 3 225 * enterAlt1 226 * location 7 5 227 * LT(1) 228 * consumeToken [c/<4>,1:0] 229 * location 7 7 230 * enterSubRule 2 231 * enter decision 2 232 * LT(1) 233 * LT(1) 234 * recognitionException NoViableAltException 2 1 2 235 * exit decision 2 236 * exitSubRule 2 237 * beginResync 238 * LT(1) 239 * consumeToken [c/<4>,1:1] 240 * LT(1) 241 * endResync 242 * LT(-1) 243 * exitRule b 244 * terminate 245 */ 246 void (*recognitionException) (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_EXCEPTION e); 247 248 /** Indicates the recognizer is about to consume tokens to resynchronize 249 * the parser. Any consume events from here until the recovered event 250 * are not part of the parse--they are dead tokens. 251 */ 252 void (*beginResync) (pANTLR3_DEBUG_EVENT_LISTENER delboy); 253 254 /** Indicates that the recognizer has finished consuming tokens in order 255 * to resynchronize. There may be multiple beginResync/endResync pairs 256 * before the recognizer comes out of errorRecovery mode (in which 257 * multiple errors are suppressed). This will be useful 258 * in a gui where you want to probably grey out tokens that are consumed 259 * but not matched to anything in grammar. Anything between 260 * a beginResync/endResync pair was tossed out by the parser. 261 */ 262 void (*endResync) (pANTLR3_DEBUG_EVENT_LISTENER delboy); 263 264 /** A semantic predicate was evaluate with this result and action text 265 */ 266 void (*semanticPredicate) (pANTLR3_DEBUG_EVENT_LISTENER delboy, ANTLR3_BOOLEAN result, const char * predicate); 267 268 /** Announce that parsing has begun. Not technically useful except for 269 * sending events over a socket. A GUI for example will launch a thread 270 * to connect and communicate with a remote parser. The thread will want 271 * to notify the GUI when a connection is made. ANTLR parsers 272 * trigger this upon entry to the first rule (the ruleLevel is used to 273 * figure this out). 274 */ 275 void (*commence) (pANTLR3_DEBUG_EVENT_LISTENER delboy); 276 277 /** Parsing is over; successfully or not. Mostly useful for telling 278 * remote debugging listeners that it's time to quit. When the rule 279 * invocation level goes to zero at the end of a rule, we are done 280 * parsing. 281 */ 282 void (*terminate) (pANTLR3_DEBUG_EVENT_LISTENER delboy); 283 284 /// Retrieve acknowledge response from the debugger. in fact this 285 /// response is never used at the moment. So we just read whatever 286 /// is in the socket buffer and throw it away. 287 /// 288 void (*ack) (pANTLR3_DEBUG_EVENT_LISTENER delboy); 289 290 // T r e e P a r s i n g 291 292 /** Input for a tree parser is an AST, but we know nothing for sure 293 * about a node except its type and text (obtained from the adaptor). 294 * This is the analog of the consumeToken method. The ID is usually 295 * the memory address of the node. 296 * If the type is UP or DOWN, then 297 * the ID is not really meaningful as it's fixed--there is 298 * just one UP node and one DOWN navigation node. 299 * 300 * Note that unlike the Java version, the node type of the C parsers 301 * is always fixed as pANTLR3_BASE_TREE because all such structures 302 * contain a super pointer to their parent, which is generally COMMON_TREE and within 303 * that there is a super pointer that can point to a user type that encapsulates it. 304 * Almost akin to saying that it is an interface pointer except we don't need to 305 * know what the interface is in full, just those bits that are the base. 306 * @param t 307 */ 308 void (*consumeNode) (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t); 309 310 /** The tree parser looked ahead. If the type is UP or DOWN, 311 * then the ID is not really meaningful as it's fixed--there is 312 * just one UP node and one DOWN navigation node. 313 */ 314 void (*LTT) (pANTLR3_DEBUG_EVENT_LISTENER delboy, int i, pANTLR3_BASE_TREE t); 315 316 317 // A S T E v e n t s 318 319 /** A nil was created (even nil nodes have a unique ID... 320 * they are not "null" per se). As of 4/28/2006, this 321 * seems to be uniquely triggered when starting a new subtree 322 * such as when entering a subrule in automatic mode and when 323 * building a tree in rewrite mode. 324 * 325 * If you are receiving this event over a socket via 326 * RemoteDebugEventSocketListener then only t.ID is set. 327 */ 328 void (*nilNode) (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t); 329 330 /** If a syntax error occurs, recognizers bracket the error 331 * with an error node if they are building ASTs. This event 332 * notifies the listener that this is the case 333 */ 334 void (*errorNode) (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t); 335 336 /** Announce a new node built from token elements such as type etc... 337 * 338 * If you are receiving this event over a socket via 339 * RemoteDebugEventSocketListener then only t.ID, type, text are 340 * set. 341 */ 342 void (*createNode) (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t); 343 344 /** Announce a new node built from an existing token. 345 * 346 * If you are receiving this event over a socket via 347 * RemoteDebugEventSocketListener then only node.ID and token.tokenIndex 348 * are set. 349 */ 350 void (*createNodeTok) (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE node, pANTLR3_COMMON_TOKEN token); 351 352 /** Make a node the new root of an existing root. See 353 * 354 * Note: the newRootID parameter is possibly different 355 * than the TreeAdaptor.becomeRoot() newRoot parameter. 356 * In our case, it will always be the result of calling 357 * TreeAdaptor.becomeRoot() and not root_n or whatever. 358 * 359 * The listener should assume that this event occurs 360 * only when the current subrule (or rule) subtree is 361 * being reset to newRootID. 362 * 363 * If you are receiving this event over a socket via 364 * RemoteDebugEventSocketListener then only IDs are set. 365 * 366 * @see org.antlr.runtime.tree.TreeAdaptor.becomeRoot() 367 */ 368 void (*becomeRoot) (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE newRoot, pANTLR3_BASE_TREE oldRoot); 369 370 /** Make childID a child of rootID. 371 * 372 * If you are receiving this event over a socket via 373 * RemoteDebugEventSocketListener then only IDs are set. 374 * 375 * @see org.antlr.runtime.tree.TreeAdaptor.addChild() 376 */ 377 void (*addChild) (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE root, pANTLR3_BASE_TREE child); 378 379 /** Set the token start/stop token index for a subtree root or node. 380 * 381 * If you are receiving this event over a socket via 382 * RemoteDebugEventSocketListener then only t.ID is set. 383 */ 384 void (*setTokenBoundaries) (pANTLR3_DEBUG_EVENT_LISTENER delboy, pANTLR3_BASE_TREE t, ANTLR3_MARKER tokenStartIndex, ANTLR3_MARKER tokenStopIndex); 385 386 /// Free up the resources allocated to this structure 387 /// 388 void (*free) (pANTLR3_DEBUG_EVENT_LISTENER delboy); 389 390 } 391 ANTLR3_DEBUG_EVENT_LISTENER; 392 393 #ifdef __cplusplus 394 } 395 #endif 396 397 #endif 398 399