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 "ANTLRBaseTree.h"
     28 #import "ANTLRBaseTreeAdaptor.h"
     29 #import "ANTLRToken.h"
     30 // TODO: this shouldn't be here...but needed for invalidNode
     31 #import "AMutableArray.h"
     32 #import "ANTLRCommonTree.h"
     33 #import "ANTLRRuntimeException.h"
     34 #import "ANTLRError.h"
     35 
     36 #pragma mark - Navigation Nodes
     37 ANTLRTreeNavigationNodeDown *navigationNodeDown = nil;
     38 ANTLRTreeNavigationNodeUp *navigationNodeUp = nil;
     39 ANTLRTreeNavigationNodeEOF *navigationNodeEOF = nil;
     40 
     41 
     42 @implementation ANTLRBaseTree
     43 
     44 static id<ANTLRBaseTree> invalidNode = nil;
     45 
     46 #pragma mark ANTLRTree protocol conformance
     47 
     48 + (id<ANTLRBaseTree>) INVALID_NODE
     49 {
     50 	if ( invalidNode == nil ) {
     51 		invalidNode = [[ANTLRCommonTree alloc] initWithTokenType:ANTLRTokenTypeInvalid];
     52 	}
     53 	return invalidNode;
     54 }
     55 
     56 + (id<ANTLRBaseTree>) invalidNode
     57 {
     58 	if ( invalidNode == nil ) {
     59 		invalidNode = [[ANTLRCommonTree alloc] initWithTokenType:ANTLRTokenTypeInvalid];
     60 	}
     61 	return invalidNode;
     62 }
     63 
     64 + newTree
     65 {
     66     return [[ANTLRBaseTree alloc] init];
     67 }
     68 
     69 /** Create a new node from an existing node does nothing for ANTLRBaseTree
     70  *  as there are no fields other than the children list, which cannot
     71  *  be copied as the children are not considered part of this node. 
     72  */
     73 + newTree:(id<ANTLRBaseTree>) node
     74 {
     75     return [[ANTLRBaseTree alloc] initWith:(id<ANTLRBaseTree>) node];
     76 }
     77 
     78 - (id) init
     79 {
     80     self = [super init];
     81     if ( self != nil ) {
     82         children = nil;
     83         return self;
     84     }
     85     return nil;
     86 }
     87 
     88 - (id) initWith:(id<ANTLRBaseTree>)node
     89 {
     90     self = [super init];
     91     if ( self != nil ) {
     92         // children = [[AMutableArray arrayWithCapacity:5] retain];
     93         // [children addObject:node];
     94         [self addChild:node];
     95         return self;
     96     }
     97     return nil;
     98 }
     99 
    100 - (void) dealloc
    101 {
    102 #ifdef DEBUG_DEALLOC
    103     NSLog( @"called dealloc in ANTLRBaseTree" );
    104 #endif
    105 	if ( children ) [children release];
    106 	[super dealloc];
    107 }
    108 
    109 - (id<ANTLRBaseTree>) getChild:(NSUInteger)i
    110 {
    111     if ( children == nil || i >= [children count] ) {
    112         return nil;
    113     }
    114     return (id<ANTLRBaseTree>)[children objectAtIndex:i];
    115 }
    116 
    117 /** Get the children internal List; note that if you directly mess with
    118  *  the list, do so at your own risk.
    119  */
    120 - (AMutableArray *) children
    121 {
    122     return children;
    123 }
    124 
    125 - (void) setChildren:(AMutableArray *)anArray
    126 {
    127     if ( children != anArray ) {
    128         if ( children ) [children release];
    129         if ( anArray ) [anArray retain];
    130     }
    131     children = anArray;
    132 }
    133 
    134 - (id<ANTLRBaseTree>) getFirstChildWithType:(NSInteger) aType
    135 {
    136     for (NSUInteger i = 0; children != nil && i < [children count]; i++) {
    137         id<ANTLRBaseTree> t = (id<ANTLRBaseTree>) [children objectAtIndex:i];
    138         if ( t.type == aType ) {
    139             return t;
    140         }
    141     }	
    142     return nil;
    143 }
    144 
    145 - (NSUInteger) getChildCount
    146 {
    147     if ( children == nil ) {
    148         return 0;
    149     }
    150     return [children count];
    151 }
    152 
    153 /** Add t as child of this node.
    154  *
    155  *  Warning: if t has no children, but child does
    156  *  and child isNil then this routine moves children to t via
    157  *  t.children = child.children; i.e., without copying the array.
    158  */
    159 - (void) addChild:(id<ANTLRBaseTree>) t
    160 {
    161     //System.out.println("add child "+t.toStringTree()+" "+self.toStringTree());
    162     //System.out.println("existing children: "+children);
    163     if ( t == nil ) {
    164         return; // do nothing upon addChild(nil)
    165     }
    166     if ( self == (ANTLRBaseTree *)t )
    167         @throw [ANTLRIllegalArgumentException newException:@"ANTLRBaseTree Can't add self to self as child"];        
    168     id<ANTLRBaseTree> childTree = (id<ANTLRBaseTree>) t;
    169     if ( [childTree isNil] ) { // t is an empty node possibly with children
    170         if ( children != nil && children == childTree.children ) {
    171             @throw [ANTLRRuntimeException newException:@"ANTLRBaseTree add child list to itself"];
    172         }
    173         // just add all of childTree's children to this
    174         if ( childTree.children != nil ) {
    175             if ( children != nil ) { // must copy, this has children already
    176                 int n = [childTree.children count];
    177                 for ( int i = 0; i < n; i++) {
    178                     id<ANTLRBaseTree> c = (id<ANTLRBaseTree>)[childTree.children objectAtIndex:i];
    179                     [children addObject:c];
    180                     // handle double-link stuff for each child of nil root
    181                     [c setParent:(id<ANTLRBaseTree>)self];
    182                     [c setChildIndex:[children count]-1];
    183                 }
    184             }
    185             else {
    186                 // no children for this but t has children; just set pointer
    187                 // call general freshener routine
    188                 children = childTree.children;
    189                 [self freshenParentAndChildIndexes];
    190             }
    191         }
    192     }
    193     else { // child is not nil (don't care about children)
    194         if ( children == nil ) {
    195             children = [[AMutableArray arrayWithCapacity:5] retain]; // create children list on demand
    196         }
    197         [children addObject:t];
    198         [childTree setParent:(id<ANTLRBaseTree>)self];
    199         [childTree setChildIndex:[children count]-1];
    200     }
    201     // System.out.println("now children are: "+children);
    202 }
    203 
    204 /** Add all elements of kids list as children of this node */
    205 - (void) addChildren:(AMutableArray *) kids
    206 {
    207     for (NSUInteger i = 0; i < [kids count]; i++) {
    208         id<ANTLRBaseTree> t = (id<ANTLRBaseTree>) [kids objectAtIndex:i];
    209         [self addChild:t];
    210     }
    211 }
    212 
    213 - (void) setChild:(NSUInteger) i With:(id<ANTLRBaseTree>)t
    214 {
    215     if ( t == nil ) {
    216         return;
    217     }
    218     if ( [t isNil] ) {
    219         @throw [ANTLRIllegalArgumentException newException:@"ANTLRBaseTree Can't set single child to a list"];        
    220     }
    221     if ( children == nil ) {
    222         children = [[AMutableArray arrayWithCapacity:5] retain];
    223     }
    224     if ([children count] > i ) {
    225         [children replaceObjectAtIndex:i withObject:t];
    226     }
    227     else {
    228         [children insertObject:t atIndex:i];
    229     }
    230     [t setParent:(id<ANTLRBaseTree>)self];
    231     [t setChildIndex:i];
    232 }
    233 
    234 - (id) deleteChild:(NSUInteger) idx
    235 {
    236     if ( children == nil ) {
    237         return nil;
    238     }
    239     id<ANTLRBaseTree> killed = (id<ANTLRBaseTree>)[children objectAtIndex:idx];
    240     [children removeObjectAtIndex:idx];
    241     // walk rest and decrement their child indexes
    242     [self freshenParentAndChildIndexes:idx];
    243     return killed;
    244 }
    245 
    246 /** Delete children from start to stop and replace with t even if t is
    247  *  a list (nil-root ANTLRTree).  num of children can increase or decrease.
    248  *  For huge child lists, inserting children can force walking rest of
    249  *  children to set their childindex; could be slow.
    250  */
    251 - (void) replaceChildrenFrom:(NSInteger)startChildIndex To:(NSInteger)stopChildIndex With:(id) t
    252 {
    253     /*
    254      System.out.println("replaceChildren "+startChildIndex+", "+stopChildIndex+
    255      " with "+((ANTLRBaseTree)t).toStringTree());
    256      System.out.println("in="+toStringTree());
    257      */
    258     if ( children == nil ) {
    259         @throw [ANTLRIllegalArgumentException newException:@"ANTLRBaseTree Invalid Indexes; no children in list"];        
    260     }
    261     int replacingHowMany = stopChildIndex - startChildIndex + 1;
    262     int replacingWithHowMany;
    263     id<ANTLRBaseTree> newTree = (id<ANTLRBaseTree>) t;
    264     AMutableArray *newChildren = nil;
    265     // normalize to a list of children to add: newChildren
    266     if ( [newTree isNil] ) {
    267         newChildren = newTree.children;
    268     }
    269     else {
    270         newChildren = [AMutableArray arrayWithCapacity:5];
    271         [newChildren addObject:newTree];
    272     }
    273     replacingWithHowMany = [newChildren count];
    274     int numNewChildren = [newChildren count];
    275     int delta = replacingHowMany - replacingWithHowMany;
    276     // if same number of nodes, do direct replace
    277     if ( delta == 0 ) {
    278         int j = 0; // index into new children
    279         for (int i=startChildIndex; i <= stopChildIndex; i++) {
    280             id<ANTLRBaseTree> child = (id<ANTLRBaseTree>)[newChildren objectAtIndex:j];
    281             [children replaceObjectAtIndex:i withObject:(id)child];
    282             [child setParent:(id<ANTLRBaseTree>)self];
    283             [child setChildIndex:i];
    284             j++;
    285         }
    286     }
    287     else if ( delta > 0 ) { // fewer new nodes than there were
    288                             // set children and then delete extra
    289         for (int j = 0; j < numNewChildren; j++) {
    290             [children replaceObjectAtIndex:startChildIndex+j withObject:[newChildren objectAtIndex:j]];
    291         }
    292         int indexToDelete = startChildIndex+numNewChildren;
    293         for (int c=indexToDelete; c<=stopChildIndex; c++) {
    294             // delete same index, shifting everybody down each time
    295             [children removeObjectAtIndex:indexToDelete];
    296         }
    297         [self freshenParentAndChildIndexes:startChildIndex];
    298     }
    299     else { // more new nodes than were there before
    300            // fill in as many children as we can (replacingHowMany) w/o moving data
    301         for (int j=0; j<replacingHowMany; j++) {
    302             [children replaceObjectAtIndex:startChildIndex+j withObject:[newChildren objectAtIndex:j]];
    303         }
    304         //        int numToInsert = replacingWithHowMany-replacingHowMany;
    305         for (int j=replacingHowMany; j<replacingWithHowMany; j++) {
    306             [children insertObject:[newChildren objectAtIndex:j] atIndex:startChildIndex+j];
    307         }
    308         [self freshenParentAndChildIndexes:startChildIndex];
    309     }
    310     //System.out.println("out="+toStringTree());
    311 }
    312 
    313 /** Override in a subclass to change the impl of children list */
    314 - (AMutableArray *) createChildrenList
    315 {
    316     return [AMutableArray arrayWithCapacity:5];
    317 }
    318 
    319 - (BOOL) isNil
    320 {
    321     return NO;
    322 }
    323 
    324 /** Set the parent and child index values for all child of t */
    325 - (void) freshenParentAndChildIndexes
    326 {
    327     [self freshenParentAndChildIndexes:0];
    328 }
    329                
    330 - (void) freshenParentAndChildIndexes:(NSInteger) offset
    331 {
    332     int n = [self getChildCount];
    333     for (int i = offset; i < n; i++) {
    334         id<ANTLRBaseTree> child = (id<ANTLRBaseTree>)[self getChild:i];
    335         [child setChildIndex:i];
    336         [child setParent:(id<ANTLRBaseTree>)self];
    337     }
    338 }
    339                
    340 - (void) sanityCheckParentAndChildIndexes
    341 {
    342     [self sanityCheckParentAndChildIndexes:nil At:-1];
    343 }
    344                
    345 - (void) sanityCheckParentAndChildIndexes:(id<ANTLRBaseTree>)aParent At:(NSInteger) i
    346 {
    347     if ( aParent != [self getParent] ) {
    348         @throw [ANTLRIllegalStateException newException:[NSString stringWithFormat:@"parents don't match; expected %s found %s", aParent, [self getParent]]];
    349     }
    350     if ( i != [self getChildIndex] ) {
    351         @throw [ANTLRIllegalStateException newException:[NSString stringWithFormat:@"child indexes don't match; expected %d found %d", i, [self getChildIndex]]];
    352     }
    353     int n = [self getChildCount];
    354     for (int c = 0; c < n; c++) {
    355         id<ANTLRBaseTree> child = (id<ANTLRBaseTree>)[self getChild:c];
    356         [child sanityCheckParentAndChildIndexes:(id<ANTLRBaseTree>)self At:c];
    357     }
    358 }
    359                
    360 /**  What is the smallest token index (indexing from 0) for this node
    361  *   and its children?
    362  */
    363 - (NSInteger) getTokenStartIndex
    364 {
    365     return 0;
    366 }
    367 
    368 - (void) setTokenStartIndex:(NSInteger) anIndex
    369 {
    370 }
    371 
    372 /**  What is the largest token index (indexing from 0) for this node
    373  *   and its children?
    374  */
    375 - (NSInteger) getTokenStopIndex
    376 {
    377     return 0;
    378 }
    379 
    380 - (void) setTokenStopIndex:(NSInteger) anIndex
    381 {
    382 }
    383 
    384 - (id<ANTLRBaseTree>) dupNode
    385 {
    386     return nil;
    387 }
    388 
    389 
    390 /** ANTLRBaseTree doesn't track child indexes. */
    391 - (NSInteger) getChildIndex
    392 {
    393     return 0;
    394 }
    395 
    396 - (void) setChildIndex:(NSInteger) anIndex
    397 {
    398 }
    399 
    400 /** ANTLRBaseTree doesn't track parent pointers. */
    401 - (id<ANTLRBaseTree>) getParent
    402 {
    403     return nil;
    404 }
    405 
    406 - (void) setParent:(id<ANTLRBaseTree>) t
    407 {
    408 }
    409 
    410 /** Walk upwards looking for ancestor with this token type. */
    411 - (BOOL) hasAncestor:(NSInteger) ttype
    412 {
    413     return([self getAncestor:ttype] != nil);
    414 }
    415 
    416 /** Walk upwards and get first ancestor with this token type. */
    417 - (id<ANTLRBaseTree>) getAncestor:(NSInteger) ttype
    418 {
    419     id<ANTLRBaseTree> t = (id<ANTLRBaseTree>)self;
    420     t = (id<ANTLRBaseTree>)[t getParent];
    421     while ( t != nil ) {
    422         if ( t.type == ttype )
    423             return t;
    424         t = (id<ANTLRBaseTree>)[t getParent];
    425     }
    426     return nil;
    427 }
    428 
    429 /** Return a list of all ancestors of this node.  The first node of
    430  *  list is the root and the last is the parent of this node.
    431  */
    432 - (AMutableArray *)getAncestors
    433 {
    434     if ( [self getParent] == nil )
    435         return nil;
    436     AMutableArray *ancestors = [AMutableArray arrayWithCapacity:5];
    437     id<ANTLRBaseTree> t = (id<ANTLRBaseTree>)self;
    438     t = (id<ANTLRBaseTree>)[t getParent];
    439     while ( t != nil ) {
    440         [ancestors insertObject:t atIndex:0]; // insert at start
    441         t = (id<ANTLRBaseTree>)[t getParent];
    442     }
    443     return ancestors;
    444 }
    445 
    446 - (NSInteger)type
    447 {
    448     return ANTLRTokenTypeInvalid;
    449 }
    450 
    451 - (NSString *)text
    452 {
    453     return nil;
    454 }
    455 
    456 - (NSUInteger)line
    457 {
    458     return 0;
    459 }
    460 
    461 - (NSUInteger)charPositionInLine
    462 {
    463     return 0;
    464 }
    465 
    466 - (void) setCharPositionInLine:(NSUInteger) pos
    467 {
    468 }
    469 
    470 #pragma mark Copying
    471      
    472      // the children themselves are not copied here!
    473 - (id) copyWithZone:(NSZone *)aZone
    474 {
    475     id<ANTLRBaseTree> theCopy = [[[self class] allocWithZone:aZone] init];
    476     [theCopy addChildren:self.children];
    477     return theCopy;
    478 }
    479      
    480 - (id) deepCopy 					// performs a deepCopyWithZone: with the default zone
    481 {
    482     return [self deepCopyWithZone:NULL];
    483 }
    484      
    485 - (id) deepCopyWithZone:(NSZone *)aZone
    486 {
    487     id<ANTLRBaseTree> theCopy = [self copyWithZone:aZone];
    488         
    489     if ( [theCopy.children count] )
    490         [theCopy.children removeAllObjects];
    491     AMutableArray *childrenCopy = theCopy.children;
    492     for (id loopItem in children) {
    493         id<ANTLRBaseTree> childCopy = [loopItem deepCopyWithZone:aZone];
    494         [theCopy addChild:childCopy];
    495     }
    496     if ( childrenCopy ) [childrenCopy release];
    497     return theCopy;
    498 }
    499      
    500 - (NSString *) treeDescription
    501 {
    502     if ( children == nil || [children count] == 0 ) {
    503         return [self description];
    504     }
    505     NSMutableString *buf = [NSMutableString stringWithCapacity:[children count]];
    506     if ( ![self isNil] ) {
    507         [buf appendString:@"("];
    508         [buf appendString:[self toString]];
    509         [buf appendString:@" "];
    510     }
    511     for (int i = 0; children != nil && i < [children count]; i++) {
    512         id<ANTLRBaseTree> t = (id<ANTLRBaseTree>)[children objectAtIndex:i];
    513         if ( i > 0 ) {
    514             [buf appendString:@" "];
    515         }
    516         [buf appendString:[(id<ANTLRBaseTree>)t toStringTree]];
    517     }
    518     if ( ![self isNil] ) {
    519         [buf appendString:@")"];
    520     }
    521     return buf;
    522 }
    523 
    524 /** Print out a whole tree not just a node */
    525 - (NSString *) toStringTree
    526 {
    527     return [self treeDescription];
    528 }
    529 
    530 - (NSString *) description
    531 {
    532     return nil;
    533 }
    534 
    535 /** Override to say how a node (not a tree) should look as text */
    536 - (NSString *) toString
    537 {
    538     return nil;
    539 }
    540 
    541 @synthesize children;
    542 @synthesize anException;
    543 
    544 @end
    545 
    546 #pragma mark -
    547 
    548 @implementation ANTLRTreeNavigationNode
    549 - (id)init
    550 {
    551     self = (ANTLRTreeNavigationNode *)[super init];
    552     return self;
    553 }
    554 
    555 - (id) copyWithZone:(NSZone *)aZone
    556 {
    557 	return nil;
    558 }
    559 @end
    560 
    561 @implementation ANTLRTreeNavigationNodeDown
    562 + (ANTLRTreeNavigationNodeDown *) getNavigationNodeDown
    563 {
    564     if ( navigationNodeDown == nil )
    565         navigationNodeDown = [[ANTLRTreeNavigationNodeDown alloc] init];
    566     return navigationNodeDown;
    567 }
    568 
    569 - (id)init
    570 {
    571     self = [super init];
    572     return self;
    573 }
    574 
    575 - (NSInteger) tokenType { return ANTLRTokenTypeDOWN; }
    576 - (NSString *) description { return @"DOWN"; }
    577 @end
    578 
    579 @implementation ANTLRTreeNavigationNodeUp
    580 + (ANTLRTreeNavigationNodeUp *) getNavigationNodeUp
    581 {
    582     if ( navigationNodeUp == nil )
    583         navigationNodeUp = [[ANTLRTreeNavigationNodeUp alloc] init];
    584     return navigationNodeUp;
    585 }
    586 
    587 
    588 - (id)init
    589 {
    590     self = [super init];
    591     return self;
    592 }
    593 
    594 - (NSInteger) tokenType { return ANTLRTokenTypeUP; }
    595 - (NSString *) description { return @"UP"; }
    596 @end
    597 
    598 @implementation ANTLRTreeNavigationNodeEOF
    599 + (ANTLRTreeNavigationNodeEOF *) getNavigationNodeEOF
    600 {
    601     if ( navigationNodeEOF == nil )
    602         navigationNodeEOF = [[ANTLRTreeNavigationNodeEOF alloc] init];
    603     return navigationNodeEOF;
    604 }
    605 
    606 - (id)init
    607 {
    608     self = [super init];
    609     return self;
    610 }
    611 
    612 - (NSInteger) tokenType { return ANTLRTokenTypeEOF; }
    613 - (NSString *) description { return @"EOF"; }
    614 
    615 @end
    616 
    617