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