xref: /aosp_15_r20/external/antlr/runtime/Cpp/include/antlr3debugeventlistener.hpp (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
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>
recognitionException(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