Home | History | Annotate | Download | only in Framework
      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 <Cocoa/Cocoa.h>
     28 #import "ANTLRToken.h"
     29 #import "ANTLRRecognitionException.h"
     30 
     31 @protocol ANTLRDebugEventListener
     32 
     33 #define ANTLRDebugProtocolVersion 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<ANTLRToken>)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<ANTLRToken>)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<ANTLRToken>)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:(ANTLRRecognitionException *)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