• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // [The "BSD licence"]
2 // Copyright (c) 2006-2007 Kay Roepke
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions
7 // are met:
8 // 1. Redistributions of source code must retain the above copyright
9 //    notice, this list of conditions and the following disclaimer.
10 // 2. Redistributions in binary form must reproduce the above copyright
11 //    notice, this list of conditions and the following disclaimer in the
12 //    documentation and/or other materials provided with the distribution.
13 // 3. The name of the author may not be used to endorse or promote products
14 //    derived from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #import <Foundation/Foundation.h>
28 #import "Token.h"
29 #import "RecognitionException.h"
30 
31 @protocol DebugEventListener
32 
33 #define DebugProtocolVersion 1
34 
35 /** The parser has just entered a rule.  No decision has been made about
36 *  which alt is predicted.  This is fired AFTER init actions have been
37 *  executed.  Attributes are defined and available etc...
38 */
39 - (void) enterRule:(NSString *)ruleName;
40 
41 /** Because rules can have lots of alternatives, it is very useful to
42 *  know which alt you are entering.  This is 1..n for n alts.
43 */
44 - (void) enterAlt:(NSInteger)alt;
45 
46 /** This is the last thing executed before leaving a rule.  It is
47 *  executed even if an exception is thrown.  This is triggered after
48 *  error reporting and recovery have occurred (unless the exception is
49 											   *  not caught in this rule).  This implies an "exitAlt" event.
50 */
51 - (void) exitRule:(NSString *)ruleName;
52 
53 /** Track entry into any (...) subrule other EBNF construct */
54 - (void) enterSubRule:(NSInteger)decisionNumber;
55 
56 - (void) exitSubRule:(NSInteger)decisionNumber;
57 
58 /** Every decision, fixed k or arbitrary, has an enter/exit event
59 *  so that a GUI can easily track what LT/consume events are
60 *  associated with prediction.  You will see a single enter/exit
61 *  subrule but multiple enter/exit decision events, one for each
62 *  loop iteration.
63 */
64 - (void) enterDecision:(NSInteger)decisionNumber;
65 
66 - (void) exitDecision:(NSInteger)decisionNumber;
67 
68 /** An input token was consumed; matched by any kind of element.
69 *  Trigger after the token was matched by things like match(), matchAny().
70 */
71 - (void) consumeToken:(id<Token>)t;
72 
73 /** An off-channel input token was consumed.
74 *  Trigger after the token was matched by things like match(), matchAny().
75 *  (unless of course the hidden token is first stuff in the input stream).
76 */
77 - (void) consumeHiddenToken:(id<Token>)t;
78 
79 /** Somebody (anybody) looked ahead.  Note that this actually gets
80 *  triggered by both LA and LT calls.  The debugger will want to know
81 *  which Token object was examined.  Like consumeToken, this indicates
82 *  what token was seen at that depth.  A remote debugger cannot look
83 *  ahead into a file it doesn't have so LT events must pass the token
84 *  even if the info is redundant.
85 */
86 - (void) LT:(NSInteger)i foundToken:(id<Token>)t;
87 
88 /** The parser is going to look arbitrarily ahead; mark this location,
89 *  the token stream's marker is sent in case you need it.
90 */
91 - (void) mark:(NSInteger)marker;
92 
93 /** After an arbitrairly long lookahead as with a cyclic DFA (or with
94 *  any backtrack), this informs the debugger that stream should be
95 *  rewound to the position associated with marker.
96 */
97 - (void) rewind:(NSInteger)marker;
98 
99 /** Rewind to the input position of the last marker.
100 *  Used currently only after a cyclic DFA and just
101 *  before starting a sem/syn predicate to get the
102 *  input position back to the start of the decision.
103 *  Do not "pop" the marker off the state.  mark(i)
104 *  and rewind(i) should balance still.
105 */
106 - (void) rewind;
107 
108 - (void) beginBacktrack:(NSInteger)level;
109 
110 - (void) endBacktrack:(NSInteger)level wasSuccessful:(BOOL)successful;
111 
112 /** To watch a parser move through the grammar, the parser needs to
113 *  inform the debugger what line/charPos it is passing in the grammar.
114 *  For now, this does not know how to switch from one grammar to the
115 *  other and back for island grammars etc...
116 *
117 *  This should also allow breakpoints because the debugger can stop
118 *  the parser whenever it hits this line/pos.
119 */
120 - (void) locationLine:(NSInteger)line column:(NSInteger)pos;
121 
122 /** A recognition exception occurred such as NoViableAltException.  I made
123 *  this a generic event so that I can alter the exception hierachy later
124 *  without having to alter all the debug objects.
125 *
126 *  Upon error, the stack of enter rule/subrule must be properly unwound.
127 *  If no viable alt occurs it is within an enter/exit decision, which
128 *  also must be rewound.  Even the rewind for each mark must be unwount.
129 *  In the Java target this is pretty easy using try/finally, if a bit
130 *  ugly in the generated code.  The rewind is generated in DFA.predict()
131 *  actually so no code needs to be generated for that.  For languages
132 *  w/o this "finally" feature (C++?), the target implementor will have
133 *  to build an event stack or something.
134 *
135 *  Across a socket for remote debugging, only the RecognitionException
136 *  data fields are transmitted.  The token object or whatever that
137 *  caused the problem was the last object referenced by LT.  The
138 *  immediately preceding LT event should hold the unexpected Token or
139 *  char.
140 *
141 *  Here is a sample event trace for grammar:
142 *
143 *  b : C ({;}A|B) // {;} is there to prevent A|B becoming a set
144 *    | D
145 *    ;
146 *
147 *  The sequence for this rule (with no viable alt in the subrule) for
148 *  input 'c c' (there are 3 tokens) is:
149 *
150 *		commence
151 *		LT(1)
152 *		enterRule b
153 *		location 7 1
154 *		enter decision 3
155 *		LT(1)
156 *		exit decision 3
157 *		enterAlt1
158 *		location 7 5
159 *		LT(1)
160 *		consumeToken [c/<4>,1:0]
161 *		location 7 7
162 *		enterSubRule 2
163 *		enter decision 2
164 *		LT(1)
165 *		LT(1)
166 *		recognitionException NoViableAltException 2 1 2
167 *		exit decision 2
168 *		exitSubRule 2
169 *		beginResync
170 *		LT(1)
171 *		consumeToken [c/<4>,1:1]
172 *		LT(1)
173 *		endResync
174 *		LT(-1)
175 *		exitRule b
176 *		terminate
177 */
178 - (void) recognitionException:(RecognitionException *)e;
179 
180 /** Indicates the recognizer is about to consume tokens to resynchronize
181 *  the parser.  Any consume events from here until the recovered event
182 *  are not part of the parse--they are dead tokens.
183 */
184 - (void) beginResync;
185 
186 /** Indicates that the recognizer has finished consuming tokens in order
187 *  to resychronize.  There may be multiple beginResync/endResync pairs
188 *  before the recognizer comes out of errorRecovery mode (in which
189 *  multiple errors are suppressed).  This will be useful
190 *  in a gui where you want to probably grey out tokens that are consumed
191 *  but not matched to anything in grammar.  Anything between
192 *  a beginResync/endResync pair was tossed out by the parser.
193 */
194 - (void) endResync;
195 
196 /** A semantic predicate was evaluate with this result and action text */
197 - (void) semanticPredicate:(NSString *)predicate matched:(BOOL)result;
198 
199 /** Announce that parsing has begun.  Not technically useful except for
200 *  sending events over a socket.  A GUI for example will launch a thread
201 *  to connect and communicate with a remote parser.  The thread will want
202 *  to notify the GUI when a connection is made.  ANTLR parsers
203 *  trigger this upon entry to the first rule (the ruleLevel is used to
204 *  figure this out).
205 */
206 - (void) commence;
207 
208 /** Parsing is over; successfully or not.  Mostly useful for telling
209 *  remote debugging listeners that it's time to quit.  When the rule
210 *  invocation level goes to zero at the end of a rule, we are done
211 *  parsing.
212 */
213 - (void) terminate;
214 
215 
216 // T r e e  P a r s i n g
217 
218 /** Input for a tree parser is an AST, but we know nothing for sure
219 *  about a node except its type and text (obtained from the adaptor).
220 *  This is the analog of the consumeToken method.  Again, the ID is
221 *  the hashCode usually of the node so it only works if hashCode is
222 *  not implemented.  If the type is UP or DOWN, then
223 *  the ID is not really meaningful as it's fixed--there is
224 *  just one UP node and one DOWN navigation node.
225 */
226 - (void) consumeNode:(NSInteger)nodeHash ofType:(NSInteger)type text:(NSString *)text;
227 
228 /** The tree parser lookedahead.  If the type is UP or DOWN,
229 *  then the ID is not really meaningful as it's fixed--there is
230 *  just one UP node and one DOWN navigation node.
231 */
232 - (void) LT:(NSInteger)i foundNode:(unsigned)nodeHash ofType:(NSInteger)type text:(NSString *)text;
233 
234 
235 // A S T  E v e n t s
236 
237 /** A nil was created (even nil nodes have a unique ID...
238 *  they are not "null" per se).  As of 4/28/2006, this
239 *  seems to be uniquely triggered when starting a new subtree
240 *  such as when entering a subrule in automatic mode and when
241 *  building a tree in rewrite mode.
242 */
243 - (void) createNilNode:(unsigned)hash;
244 
245 /** Announce a new node built from text */
246 - (void) createNode:(unsigned)hash text:(NSString *)text type:(NSInteger)type;
247 
248 /** Announce a new node built from an existing token */
249 - (void) createNode:(unsigned)hash fromTokenAtIndex:(NSInteger)tokenIndex;
250 
251 /** Make a node the new root of an existing root.  See
252 *
253 *  Note: the newRootID parameter is possibly different
254 *  than the TreeAdaptor.becomeRoot() newRoot parameter.
255 *  In our case, it will always be the result of calling
256 *  TreeAdaptor.becomeRoot() and not root_n or whatever.
257 *
258 *  The listener should assume that this event occurs
259 *  only when the current subrule (or rule) subtree is
260 *  being reset to newRootID.
261 *
262 */
263 - (void) makeNode:(unsigned)newRootHash parentOf:(unsigned)oldRootHash;
264 
265 /** Make childID a child of rootID.
266 *  @see org.antlr.runtime.tree.TreeAdaptor.addChild()
267 */
268 - (void) addChild:(unsigned)childHash toTree:(unsigned)treeHash;
269 
270 /** Set the token start/stop token index for a subtree root or node */
271 - (void) setTokenBoundariesForTree:(unsigned)nodeHash From:(NSUInteger)tokenStartIndex To:(NSUInteger)tokenStopIndex;
272 
273 - (void) waitForDebuggerConnection;
274 
275 @end
276