Home | History | Annotate | Download | only in Framework
      1 // [The "BSD licence"]
      2 // Copyright (c) 2006-2007 Kay Roepke 2010 Alan Condit
      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 "ANTLRTreeParser.h"
     28 
     29 @implementation ANTLRTreeParser
     30 
     31 @synthesize input;
     32 
     33 + (id) newANTLRTreeParser:(id<ANTLRTreeNodeStream>)anInput
     34 {
     35     return [[ANTLRTreeParser alloc] initWithStream:anInput];
     36 }
     37 
     38 + (id) newANTLRTreeParser:(id<ANTLRTreeNodeStream>)anInput State:(ANTLRRecognizerSharedState *)theState
     39 {
     40     return [[ANTLRTreeParser alloc] initWithStream:anInput State:theState];
     41 }
     42 
     43 - (id) initWithStream:(id<ANTLRTreeNodeStream>)theInput
     44 {
     45 	if ((self = [super init]) != nil) {
     46 		[self setInput:theInput];
     47 	}
     48 	return self;
     49 }
     50 
     51 - (id) initWithStream:(id<ANTLRTreeNodeStream>)theInput State:(ANTLRRecognizerSharedState *)theState
     52 {
     53 	if ((self = [super init]) != nil) {
     54 		[self setInput:theInput];
     55         state = theState;
     56 	}
     57 	return self;
     58 }
     59 
     60 - (void) dealloc
     61 {
     62 #ifdef DEBUG_DEALLOC
     63     NSLog( @"called dealloc in ANTLRTreeParser" );
     64 #endif
     65 	if ( input ) [input release];
     66 	[super dealloc];
     67 }
     68 
     69 - (void) reset
     70 {
     71     [super reset]; // reset all recognizer state variables
     72     if ( input != nil ) {
     73         [input seek:0]; // rewind the input
     74     }
     75 }
     76 
     77 - (void) mismatch:(id<ANTLRIntStream>)aStream tokenType:(ANTLRTokenType)aTType follow:(ANTLRBitSet *)aBitset
     78 {
     79 	ANTLRMismatchedTreeNodeException *mte = [ANTLRMismatchedTreeNodeException newException:aTType Stream:aStream];
     80     [mte setNode:[((id<ANTLRTreeNodeStream>)aStream) LT:1]];
     81 	[self recoverFromMismatchedToken:aStream Type:aTType Follow:aBitset];
     82 }
     83 
     84 - (void) setTreeNodeStream:(id<ANTLRTreeNodeStream>) anInput
     85 {
     86     input = anInput;
     87 }
     88 
     89 - (id<ANTLRTreeNodeStream>) getTreeNodeStream
     90 {
     91     return input;
     92 }
     93 
     94 - (NSString *)getSourceName
     95 {
     96     return [input getSourceName];
     97 }
     98 
     99 - (id) getCurrentInputSymbol:(id<ANTLRIntStream>) anInput
    100 {
    101     return [(id<ANTLRTreeNodeStream>)anInput LT:1];
    102 }
    103 
    104 - (id) getMissingSymbol:(id<ANTLRIntStream>)anInput
    105               Exception:(ANTLRRecognitionException *)e
    106           ExpectedToken:(NSInteger)expectedTokenType
    107                  BitSet:(ANTLRBitSet *)follow
    108 {
    109     NSString *tokenText =[NSString stringWithFormat:@"<missing %@ %d>", [self getTokenNames], expectedTokenType];
    110     //id<ANTLRTreeAdaptor> anAdaptor = (id<ANTLRTreeAdaptor>)[((id<ANTLRTreeNodeStream>)e.input) getTreeAdaptor];
    111     //return [anAdaptor createToken:expectedTokenType Text:tokenText];
    112     return [ANTLRCommonToken newToken:expectedTokenType Text:tokenText];
    113 }
    114 
    115 /** Match '.' in tree parser has special meaning.  Skip node or
    116  *  entire tree if node has children.  If children, scan until
    117  *  corresponding UP node.
    118  */
    119 - (void) matchAny:(id<ANTLRIntStream>)ignore
    120 { // ignore stream, copy of input
    121     state.errorRecovery = NO;
    122     state.failed = NO;
    123     id look = [input LT:1];
    124     if ( [((ANTLRCommonTreeAdaptor *)[input getTreeAdaptor]) getChildCount:look] == 0) {
    125         [input consume]; // not subtree, consume 1 node and return
    126         return;
    127     }
    128     // current node is a subtree, skip to corresponding UP.
    129     // must count nesting level to get right UP
    130     int level=0;
    131     int tokenType = [((id<ANTLRTreeAdaptor>)[input getTreeAdaptor]) getType:look];
    132     while ( tokenType != ANTLRTokenTypeEOF && !( tokenType == ANTLRTokenTypeUP && level == 0) ) {
    133         [input consume];
    134         look = [input LT:1];
    135         tokenType = [((id<ANTLRTreeAdaptor>)[input getTreeAdaptor]) getType:look];
    136         if ( tokenType == ANTLRTokenTypeDOWN ) {
    137             level++;
    138         }
    139         else if ( tokenType == ANTLRTokenTypeUP ) {
    140             level--;
    141         }
    142     }
    143     [input consume]; // consume UP
    144 }
    145 
    146 /** We have DOWN/UP nodes in the stream that have no line info; override.
    147  *  plus we want to alter the exception type.  Don't try to recover
    148  *  from tree parser errors inline...
    149  */
    150 - (id) recoverFromMismatchedToken:(id<ANTLRIntStream>)anInput Type:(NSInteger)ttype Follow:(ANTLRBitSet *)follow
    151 {
    152     @throw [ANTLRMismatchedTreeNodeException newException:ttype Stream:anInput];
    153 }
    154 
    155 /** Prefix error message with the grammar name because message is
    156  *  always intended for the programmer because the parser built
    157  *  the input tree not the user.
    158  */
    159 - (NSString *)getErrorHeader:(ANTLRRecognitionException *)e
    160 {
    161      return [NSString stringWithFormat:@"%@: node after line %@:%@",
    162             [self getGrammarFileName], e.line, e.charPositionInLine];
    163 }
    164 
    165 /** Tree parsers parse nodes they usually have a token object as
    166  *  payload. Set the exception token and do the default behavior.
    167  */
    168 - (NSString *)getErrorMessage:(ANTLRRecognitionException *)e  TokenNames:(AMutableArray *) theTokNams
    169 {
    170     if ( [self isKindOfClass:[ANTLRTreeParser class]] ) {
    171         ANTLRCommonTreeAdaptor *adaptor = (ANTLRCommonTreeAdaptor *)[((id<ANTLRTreeNodeStream>)e.input) getTreeAdaptor];
    172         e.token = [adaptor getToken:((id<ANTLRBaseTree>)e.node)];
    173         if ( e.token == nil ) { // could be an UP/DOWN node
    174             e.token = [ANTLRCommonToken newToken:[adaptor getType:e.node]
    175                                                         Text:[adaptor getText:e.node]];
    176         }
    177     }
    178     return [super getErrorMessage:e TokenNames:theTokNams];
    179 }
    180 
    181 - (void) traceIn:(NSString *)ruleName Index:(NSInteger)ruleIndex
    182 {
    183     [super traceIn:ruleName Index:ruleIndex Object:[input LT:1]];
    184 }
    185 
    186 - (void) traceOut:(NSString *)ruleName Index:(NSInteger)ruleIndex
    187 {
    188     [super traceOut:ruleName Index:ruleIndex  Object:[input LT:1]];
    189 }
    190 
    191 
    192 @end
    193