Home | History | Annotate | Download | only in include
      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