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 "ANTLRCommonTreeNodeStream.h"
     28 #import "ANTLRTokenStream.h"
     29 #import "ANTLRIntStream.h"
     30 #import "ANTLRCharStream.h"
     31 #import "AMutableArray.h"
     32 #import "ANTLRCommonTreeAdaptor.h"
     33 
     34 #ifndef DEBUG_DEALLOC
     35 #define DEBUG_DEALLOC
     36 #endif
     37 
     38 @implementation ANTLRCommonTreeNodeStream
     39 
     40 @synthesize root;
     41 @synthesize tokens;
     42 @synthesize adaptor;
     43 @synthesize level;
     44 
     45 + (ANTLRCommonTreeNodeStream *) newANTLRCommonTreeNodeStream:(ANTLRCommonTree *)theTree
     46 {
     47     return [[ANTLRCommonTreeNodeStream alloc] initWithTree:theTree];
     48 }
     49 
     50 + (ANTLRCommonTreeNodeStream *) newANTLRCommonTreeNodeStream:(id<ANTLRTreeAdaptor>)anAdaptor Tree:(ANTLRCommonTree *)theTree
     51 {
     52     return [[ANTLRCommonTreeNodeStream alloc] initWithTreeAdaptor:anAdaptor Tree:theTree];
     53 }
     54 
     55 - (id) initWithTree:(ANTLRCommonTree *)theTree
     56 {
     57     if ((self = [super init]) != nil ) {
     58         adaptor = [[ANTLRCommonTreeAdaptor newTreeAdaptor] retain];
     59         root = [theTree retain];
     60         navigationNodeEOF = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain]; // set EOF
     61         it = [[ANTLRTreeIterator newANTRLTreeIteratorWithAdaptor:adaptor andTree:root] retain];
     62         calls = [[ANTLRIntArray newArrayWithLen:INITIAL_CALL_STACK_SIZE] retain];
     63         /** Tree (nil A B C) trees like flat A B C streams */
     64         hasNilRoot = NO;
     65         level = 0;
     66     }
     67     return self;
     68 }
     69 
     70 - (id) initWithTreeAdaptor:(id<ANTLRTreeAdaptor>)anAdaptor Tree:(ANTLRCommonTree *)theTree
     71 {
     72     if ((self = [super init]) != nil ) {
     73         adaptor = [anAdaptor retain];
     74         root = [theTree retain];
     75         navigationNodeEOF = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain]; // set EOF
     76         //    it = [root objectEnumerator];
     77         it = [[ANTLRTreeIterator newANTRLTreeIteratorWithAdaptor:adaptor andTree:root] retain];
     78         calls = [[ANTLRIntArray newArrayWithLen:INITIAL_CALL_STACK_SIZE] retain];
     79         /** Tree (nil A B C) trees like flat A B C streams */
     80         hasNilRoot = NO;
     81         level = 0;
     82     }
     83     //    eof = [self isEOF]; // make sure tree iterator returns the EOF we want
     84     return self;
     85 }
     86 
     87 - (void)dealloc
     88 {
     89 #ifdef DEBUG_DEALLOC
     90     NSLog( @"called dealloc in ANTLRCommonTreeNodeStream" );
     91 #endif
     92     if ( root ) [root release];
     93     if ( tokens ) [tokens release];
     94     if ( adaptor ) [adaptor release];
     95     if ( it ) [it release];
     96     if ( calls ) [calls release];    
     97     [super dealloc];
     98 }
     99 
    100 - (void) reset
    101 {
    102     [super reset];
    103     [it reset];
    104     hasNilRoot = false;
    105     level = 0;
    106     if ( calls != nil )
    107         [calls reset];  // [calls clear]; // in Java
    108 }
    109 
    110 /** Pull elements from tree iterator.  Track tree level 0..max_level.
    111  *  If nil rooted tree, don't give initial nil and DOWN nor final UP.
    112  */
    113 - (id) nextElement
    114 {
    115     id t = [it nextObject];
    116     //System.out.println("pulled "+adaptor.getType(t));
    117     if ( t == [it up] ) {
    118         level--;
    119         if ( level==0 && hasNilRoot ) return [it nextObject]; // don't give last UP; get EOF
    120     }
    121     else if ( t == [it down] )
    122         level++;
    123     if ( level == 0 && [adaptor isNil:t] ) { // if nil root, scarf nil, DOWN
    124         hasNilRoot = true;
    125         t = [it nextObject]; // t is now DOWN, so get first real node next
    126         level++;
    127         t = [it nextObject];
    128     }
    129     return t;
    130 }
    131 
    132 - (BOOL) isEOF:(id<ANTLRBaseTree>) aTree
    133 {
    134     return [adaptor getType:(ANTLRCommonTree *)aTree] == ANTLRTokenTypeEOF;
    135 }
    136 
    137 - (void) setUniqueNavigationNodes:(BOOL) uniqueNavigationNodes
    138 {
    139 }
    140 
    141 - (id) getTreeSource
    142 {
    143     return root;
    144 }
    145 
    146 - (NSString *) getSourceName
    147 {
    148     return [[self getTokenStream] getSourceName];
    149 }
    150 
    151 - (id<ANTLRTokenStream>) getTokenStream
    152 {
    153     return tokens;
    154 }
    155 
    156 - (void) setTokenStream:(id<ANTLRTokenStream>)theTokens
    157 {
    158     if ( tokens != theTokens ) {
    159         if ( tokens ) [tokens release];
    160         [theTokens retain];
    161     }
    162     tokens = theTokens;
    163 }
    164 
    165 - (ANTLRCommonTreeAdaptor *) getTreeAdaptor
    166 {
    167     return adaptor;
    168 }
    169 
    170 - (void) setTreeAdaptor:(ANTLRCommonTreeAdaptor *) anAdaptor
    171 {
    172     if ( adaptor != anAdaptor ) {
    173         if ( adaptor ) [adaptor release];
    174         [anAdaptor retain];
    175     }
    176     adaptor = anAdaptor;
    177 }
    178 
    179 - (ANTLRCommonTree *)getNode:(NSInteger) i
    180 {
    181     @throw [ANTLRRuntimeException newException:@"Absolute node indexes are meaningless in an unbuffered stream"];
    182     return nil;
    183 }
    184 
    185 - (NSInteger) LA:(NSInteger) i
    186 {
    187     return [adaptor getType:[self LT:i]];
    188 }
    189 
    190 /** Make stream jump to a new location, saving old location.
    191  *  Switch back with pop().
    192  */
    193 - (void) push:(NSInteger) anIndex
    194 {
    195     if ( calls == nil ) {
    196         calls = [[ANTLRIntArray newArrayWithLen:INITIAL_CALL_STACK_SIZE] retain];
    197     }
    198     [calls push:p]; // save current anIndex
    199     [self seek:anIndex];
    200 }
    201 
    202 /** Seek back to previous anIndex saved during last push() call.
    203  *  Return top of stack (return anIndex).
    204  */
    205 - (NSInteger) pop
    206 {
    207     int ret = [calls pop];
    208     [self seek:ret];
    209     return ret;
    210 }    
    211 
    212 // TREE REWRITE INTERFACE
    213 
    214 - (void) replaceChildren:(id) parent From:(NSInteger)startChildIndex To:(NSInteger)stopChildIndex With:(id) aTree
    215 {
    216     if ( parent != nil ) {
    217         [adaptor replaceChildren:parent From:startChildIndex To:stopChildIndex With:aTree];
    218     }
    219 }
    220 
    221 - (NSString *) toStringFromNode:(id<ANTLRBaseTree>)startNode ToNode:(id<ANTLRBaseTree>)stopNode
    222 {
    223     // we'll have to walk from start to stop in tree; we're not keeping
    224     // a complete node stream buffer
    225     return @"n/a";
    226 }
    227 
    228 /** For debugging; destructive: moves tree iterator to end. */
    229 - (NSString *) toTokenTypeString
    230 {
    231     [self reset];
    232     NSMutableString *buf = [NSMutableString stringWithCapacity:5];
    233     id obj = [self LT:1];
    234     NSInteger type = [adaptor getType:obj];
    235     while ( type != ANTLRTokenTypeEOF ) {
    236         [buf appendString:@" "];
    237         [buf appendString:[NSString stringWithFormat:@"%d", type]];
    238         [self consume];
    239         obj = [self LT:1];
    240         type = [adaptor getType:obj];
    241     }
    242     return buf;
    243 }
    244 
    245 @synthesize it;
    246 @synthesize calls;
    247 @synthesize hasNilRoot;
    248 @end
    249 
    250