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 37ANTLRTreeNavigationNodeDown *navigationNodeDown = nil; 38ANTLRTreeNavigationNodeUp *navigationNodeUp = nil; 39ANTLRTreeNavigationNodeEOF *navigationNodeEOF = nil; 40 41 42@implementation ANTLRBaseTree 43 44static 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