1// 2// ANTLRBufferedTreeNodeStream.m 3// ANTLR 4// 5// [The "BSD licence"] 6// Copyright (c) 2010 Ian Michell 2010 Alan Condit 7// All rights reserved. 8// 9// Redistribution and use in source and binary forms, with or without 10// modification, are permitted provided that the following conditions 11// are met: 12// 1. Redistributions of source code must retain the above copyright 13// notice, this list of conditions and the following disclaimer. 14// 2. Redistributions in binary form must reproduce the above copyright 15// notice, this list of conditions and the following disclaimer in the 16// documentation and/or other materials provided with the distribution. 17// 3. The name of the author may not be used to endorse or promote products 18// derived from this software without specific prior written permission. 19// 20// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31#import "ANTLRBufferedTreeNodeStream.h" 32#import "ANTLRStreamEnumerator.h" 33#import "ANTLRCommonTreeAdaptor.h" 34 35extern NSInteger debug; 36 37#ifdef DONTUSENOMO 38@implementation ANTLRTreeStreamIterator 39+ newANTLRTreeStreamIteratorWithNodes:(ANTLRBufferedTreeNodeStream *)theStream 40{ 41 return[[ANTLRTreeStreamIterator alloc] initWithStream:theStream]; 42} 43 44- (id) initWithStream:(ANTLRBufferedTreeNodeStream *)theStream 45{ 46 if ((self = [super init]) != nil) { 47 idx = 0; 48 input = theStream; 49 nodes = [theStream getNodes]; 50 } 51 return self; 52} 53 54- (BOOL) hasNext 55{ 56 return idx < [nodes count]; 57} 58 59- (id) next 60{ 61 NSInteger current = idx; 62 idx++; 63 if (current < [nodes count]) { 64 } 65 return [nodes getEof]; 66} 67 68- (void) remove 69{ 70 @throw [ANTLRRuntimeException newException:@"cannot remove nodes from stream"]; 71} 72 73@end 74#endif 75 76@implementation ANTLRBufferedTreeNodeStream 77 78@synthesize up; 79@synthesize down; 80@synthesize eof; 81@synthesize nodes; 82@synthesize root; 83@synthesize tokens; 84@synthesize adaptor; 85@synthesize uniqueNavigationNodes; 86@synthesize index; 87@synthesize lastMarker; 88@synthesize calls; 89@synthesize e; 90@synthesize currentSymbol; 91 92+ (ANTLRBufferedTreeNodeStream *) newANTLRBufferedTreeNodeStream:(ANTLRCommonTree *) aTree 93{ 94 return [((ANTLRBufferedTreeNodeStream *)[ANTLRBufferedTreeNodeStream alloc]) initWithTree:(ANTLRCommonTree *)aTree]; 95} 96 97+ (ANTLRBufferedTreeNodeStream *) newANTLRBufferedTreeNodeStream:(id<ANTLRTreeAdaptor>)adaptor Tree:(ANTLRCommonTree *)aTree 98{ 99 return [[ANTLRBufferedTreeNodeStream alloc] initWithTreeAdaptor:adaptor Tree:(ANTLRCommonTree *)aTree]; 100} 101 102+ (ANTLRBufferedTreeNodeStream *) newANTLRBufferedTreeNodeStream:(id<ANTLRTreeAdaptor>)adaptor Tree:(ANTLRCommonTree *)aTree withBufferSize:(NSInteger)initialBufferSize 103{ 104 return [[ANTLRBufferedTreeNodeStream alloc] initWithTreeAdaptor:adaptor Tree:(ANTLRCommonTree *)aTree WithBufferSize:initialBufferSize]; 105} 106 107-(ANTLRBufferedTreeNodeStream *) init 108{ 109 self = [super init]; 110 if (self) { 111 index = -1; 112 uniqueNavigationNodes = NO; 113 root = [[ANTLRCommonTree alloc] init]; 114 // tokens = tree; 115 adaptor = [[[ANTLRCommonTreeAdaptor alloc] init] retain]; 116 nodes = [[AMutableArray arrayWithCapacity:DEFAULT_INITIAL_BUFFER_SIZE] retain]; 117 down = [[adaptor createTree:ANTLRTokenTypeDOWN Text:@"DOWN"] retain]; 118 up = [[adaptor createTree:ANTLRTokenTypeUP Text:@"UP"] retain]; 119 eof = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain]; 120 } 121 return self; 122} 123 124- (ANTLRBufferedTreeNodeStream *)initWithTree:(ANTLRCommonTree *) aTree 125{ 126 self = [super init]; 127 if (self) { 128 index = -1; 129 uniqueNavigationNodes = NO; 130 root = aTree; 131 // tokens = aTree; 132 adaptor = [[[ANTLRCommonTreeAdaptor alloc] init] retain]; 133 nodes = [[AMutableArray arrayWithCapacity:DEFAULT_INITIAL_BUFFER_SIZE] retain]; 134 down = [[adaptor createTree:ANTLRTokenTypeDOWN Text:@"DOWN"] retain]; 135 up = [[adaptor createTree:ANTLRTokenTypeUP Text:@"UP"] retain]; 136 eof = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain]; 137 } 138 return self; 139} 140 141-(ANTLRBufferedTreeNodeStream *) initWithTreeAdaptor:(ANTLRCommonTreeAdaptor *)anAdaptor Tree:(ANTLRCommonTree *)aTree 142{ 143 self = [super init]; 144 if (self) { 145 index = -1; 146 uniqueNavigationNodes = NO; 147 root = aTree; 148 // tokens = aTree; 149 adaptor = [anAdaptor retain]; 150 nodes = [[AMutableArray arrayWithCapacity:DEFAULT_INITIAL_BUFFER_SIZE] retain]; 151 down = [[adaptor createTree:ANTLRTokenTypeDOWN Text:@"DOWN"] retain]; 152 up = [[adaptor createTree:ANTLRTokenTypeUP Text:@"UP"] retain]; 153 eof = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain]; 154 } 155 return self; 156} 157 158-(ANTLRBufferedTreeNodeStream *) initWithTreeAdaptor:(ANTLRCommonTreeAdaptor *)anAdaptor Tree:(ANTLRCommonTree *)aTree WithBufferSize:(NSInteger)bufferSize 159{ 160 self = [super init]; 161 if (self) { 162 // down = [adaptor createToken:ANTLRTokenTypeDOWN withText:@"DOWN"]; 163 // up = [adaptor createToken:ANTLRTokenTypeDOWN withText:@"UP"]; 164 // eof = [adaptor createToken:ANTLRTokenTypeDOWN withText:@"EOF"]; 165 index = -1; 166 uniqueNavigationNodes = NO; 167 root = aTree; 168 // tokens = aTree; 169 adaptor = [anAdaptor retain]; 170 nodes = [[AMutableArray arrayWithCapacity:bufferSize] retain]; 171 down = [[adaptor createTree:ANTLRTokenTypeDOWN Text:@"DOWN"] retain]; 172 up = [[adaptor createTree:ANTLRTokenTypeUP Text:@"UP"] retain]; 173 eof = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain]; 174 } 175 return self; 176} 177 178- (void)dealloc 179{ 180#ifdef DEBUG_DEALLOC 181 NSLog( @"called dealloc in ANTLRBufferedTreeNodeStream" ); 182#endif 183 if ( adaptor ) [adaptor release]; 184 if ( nodes ) [nodes release]; 185 if ( root ) [root release]; 186 if ( down ) [down release]; 187 if ( up ) [up release]; 188 if ( eof ) [eof release]; 189 [super dealloc]; 190} 191 192- (id) copyWithZone:(NSZone *)aZone 193{ 194 ANTLRBufferedTreeNodeStream *copy; 195 196 copy = [[[self class] allocWithZone:aZone] init]; 197 if ( up ) 198 copy.up = [up copyWithZone:aZone]; 199 if ( down ) 200 copy.down = [down copyWithZone:aZone]; 201 if ( eof ) 202 copy.eof = [eof copyWithZone:aZone]; 203 if ( nodes ) 204 copy.nodes = [nodes copyWithZone:aZone]; 205 if ( root ) 206 copy.root = [root copyWithZone:aZone]; 207 if ( tokens ) 208 copy.tokens = [tokens copyWithZone:aZone]; 209 if ( adaptor ) 210 copy.adaptor = [adaptor copyWithZone:aZone]; 211 copy.uniqueNavigationNodes = self.uniqueNavigationNodes; 212 copy.index = self.index; 213 copy.lastMarker = self.lastMarker; 214 if ( calls ) 215 copy.calls = [calls copyWithZone:aZone]; 216 return copy; 217} 218 219// protected methods. DO NOT USE 220#pragma mark Protected Methods 221-(void) fillBuffer 222{ 223 [self fillBufferWithTree:root]; 224 // if (debug > 1) NSLog("revIndex=%@", tokenTypeToStreamIndexesMap); 225 index = 0; // buffer of nodes intialized now 226} 227 228-(void) fillBufferWithTree:(ANTLRCommonTree *) aTree 229{ 230 BOOL empty = [adaptor isNil:aTree]; 231 if (!empty) { 232 [nodes addObject:aTree]; 233 } 234 NSInteger n = [adaptor getChildCount:aTree]; 235 if (!empty && n > 0) { 236 [self addNavigationNode:ANTLRTokenTypeDOWN]; 237 } 238 for (NSInteger c = 0; c < n; c++) { 239 id child = [adaptor getChild:aTree At:c]; 240 [self fillBufferWithTree:child]; 241 } 242 if (!empty && n > 0) { 243 [self addNavigationNode:ANTLRTokenTypeUP]; 244 } 245} 246 247-(NSInteger) getNodeIndex:(ANTLRCommonTree *) node 248{ 249 if (index == -1) { 250 [self fillBuffer]; 251 } 252 for (NSUInteger i = 0; i < [nodes count]; i++) { 253 id t = [nodes objectAtIndex:i]; 254 if (t == node) { 255 return i; 256 } 257 } 258 return -1; 259} 260 261-(void) addNavigationNode:(NSInteger) type 262{ 263 id navNode = nil; 264 if (type == ANTLRTokenTypeDOWN) { 265 if (self.uniqueNavigationNodes) { 266 navNode = [adaptor createToken:ANTLRTokenTypeDOWN Text:@"DOWN"]; 267 } 268 else { 269 navNode = down; 270 } 271 272 } 273 else { 274 if (self.uniqueNavigationNodes) { 275 navNode = [adaptor createToken:ANTLRTokenTypeUP Text:@"UP"]; 276 } 277 else { 278 navNode = up; 279 } 280 } 281 [nodes addObject:navNode]; 282} 283 284-(id) getNode:(NSUInteger) i 285{ 286 if (index == -1) { 287 [self fillBuffer]; 288 } 289 return [nodes objectAtIndex:i]; 290} 291 292-(id) LT:(NSInteger) k 293{ 294 if (index == -1) { 295 [self fillBuffer]; 296 } 297 if (k == 0) { 298 return nil; 299 } 300 if (k < 0) { 301 return [self LB:-k]; 302 } 303 if ((index + k - 1) >= [nodes count]) { 304 return eof; 305 } 306 return [nodes objectAtIndex:(index + k - 1)]; 307} 308 309-(id) getCurrentSymbol 310{ 311 return [self LT:1]; 312} 313 314-(id) LB:(NSInteger) k 315{ 316 if (k == 0) { 317 return nil; 318 } 319 if ((index - k) < 0) { 320 return nil; 321 } 322 return [nodes objectAtIndex:(index - k)]; 323} 324 325- (ANTLRCommonTree *)getTreeSource 326{ 327 return root; 328} 329 330-(NSString *)getSourceName 331{ 332 return [[self getTokenStream] getSourceName]; 333} 334 335- (id<ANTLRTokenStream>)getTokenStream 336{ 337 return tokens; 338} 339 340- (void) setTokenStream:(id<ANTLRTokenStream>)newtokens 341{ 342 tokens = newtokens; 343} 344 345- (id<ANTLRTreeAdaptor>)getTreeAdaptor 346{ 347 return adaptor; 348} 349 350- (void) setTreeAdaptor:(id<ANTLRTreeAdaptor>)anAdaptor 351{ 352 adaptor = anAdaptor; 353} 354 355- (BOOL)getUniqueNavigationNodes 356{ 357 return uniqueNavigationNodes; 358} 359 360- (void) setUniqueNavigationNodes:(BOOL)aVal 361{ 362 uniqueNavigationNodes = aVal; 363} 364 365-(void) consume 366{ 367 if (index == -1) { 368 [self fillBuffer]; 369 } 370 index++; 371} 372 373-(NSInteger) LA:(NSInteger) i 374{ 375 return [adaptor getType:[self LT:i]]; 376} 377 378-(NSInteger) mark 379{ 380 if (index == -1) { 381 [self fillBuffer]; 382 } 383 lastMarker = self.index; 384 return lastMarker; 385} 386 387-(void) release:(NSInteger) marker 388{ 389 // do nothing 390} 391 392-(void) rewind:(NSInteger) marker 393{ 394 [self seek:marker]; 395} 396 397-(void) rewind 398{ 399 [self seek:lastMarker]; 400} 401 402-(void) seek:(NSInteger) i 403{ 404 if (index == -1) { 405 [self fillBuffer]; 406 } 407 index = i; 408} 409 410-(void) push:(NSInteger) i 411{ 412 if (calls == nil) { 413 calls = [ANTLRIntArray newArrayWithLen:INITIAL_CALL_STACK_SIZE]; 414 } 415 [calls push:index]; 416 [self seek:i]; 417} 418 419-(NSInteger) pop 420{ 421 NSInteger ret = [calls pop]; 422 [self seek:ret]; 423 return ret; 424} 425 426-(void) reset 427{ 428 index = 0; 429 lastMarker = 0; 430 if (calls != nil) { 431 [calls reset]; 432 } 433} 434 435-(NSUInteger) count 436{ 437 if (index == -1) { 438 [self fillBuffer]; 439 } 440 return [nodes count]; 441} 442 443-(NSUInteger) size 444{ 445 return [self count]; 446} 447 448-(NSEnumerator *) objectEnumerator 449{ 450 if (e == nil) { 451 e = [[ANTLRStreamEnumerator alloc] initWithNodes:nodes andEOF:eof]; 452 } 453 return e; 454} 455 456-(void) replaceChildren:(ANTLRCommonTree *) parent From:(NSInteger)startIdx To:(NSInteger)stopIdx With:(ANTLRCommonTree *)aTree 457{ 458 if (parent != nil) { 459 [adaptor replaceChildren:parent From:startIdx To:stopIdx With:aTree]; 460 } 461} 462 463-(NSString *) toTokenTypeString 464{ 465 if (index == -1) 466 { 467 [self fillBuffer]; 468 } 469 NSMutableString *buf = [NSMutableString stringWithCapacity:10]; 470 for (NSUInteger i= 0; i < [nodes count]; i++) { 471 ANTLRCommonTree * aTree = (ANTLRCommonTree *)[self getNode:i]; 472 [buf appendFormat:@" %d", [adaptor getType:aTree]]; 473 } 474 return buf; 475} 476 477-(NSString *) toTokenString:(NSInteger)aStart ToEnd:(NSInteger)aStop 478{ 479 if (index == -1) { 480 [self fillBuffer]; 481 } 482 NSMutableString *buf = [NSMutableString stringWithCapacity:10]; 483 for (NSUInteger i = aStart; i < [nodes count] && i <= aStop; i++) { 484 ANTLRCommonTree * t = (ANTLRCommonTree *)[self getNode:i]; 485 [buf appendFormat:@" %d", [adaptor getType:t]]; 486 } 487 return buf; 488} 489 490-(NSString *) toStringFromNode:(id)aStart ToNode:(id)aStop 491{ 492 if (aStart == nil || aStop == nil) { 493 return nil; 494 } 495 if (index == -1) { 496 [self fillBuffer]; 497 } 498 499 // if we have a token stream, use that to dump text in order 500 if ([self getTokenStream] != nil) { 501 NSInteger beginTokenIndex = [adaptor getTokenStartIndex:aStart]; 502 NSInteger endTokenIndex = [adaptor getTokenStopIndex:aStop]; 503 504 if ([adaptor getType:aStop] == ANTLRTokenTypeUP) { 505 endTokenIndex = [adaptor getTokenStopIndex:aStart]; 506 } 507 else if ([adaptor getType:aStop] == ANTLRTokenTypeEOF) { 508 endTokenIndex = [self count] - 2; //don't use EOF 509 } 510 [tokens toStringFromStart:beginTokenIndex ToEnd:endTokenIndex]; 511 } 512 // walk nodes looking for aStart 513 ANTLRCommonTree * aTree = nil; 514 NSUInteger i = 0; 515 for (; i < [nodes count]; i++) { 516 aTree = [nodes objectAtIndex:i]; 517 if (aTree == aStart) { 518 break; 519 } 520 } 521 NSMutableString *buf = [NSMutableString stringWithCapacity:10]; 522 aTree = [nodes objectAtIndex:i]; // why? 523 while (aTree != aStop) { 524 NSString *text = [adaptor getText:aTree]; 525 if (text == nil) { 526 text = [NSString stringWithFormat:@" %d", [adaptor getType:aTree]]; 527 } 528 [buf appendString:text]; 529 i++; 530 aTree = [nodes objectAtIndex:i]; 531 } 532 NSString *text = [adaptor getText:aStop]; 533 if (text == nil) { 534 text = [NSString stringWithFormat:@" %d", [adaptor getType:aStop]]; 535 } 536 [buf appendString:text]; 537 return buf; 538} 539 540// getters and setters 541- (AMutableArray *) getNodes 542{ 543 return nodes; 544} 545 546- (id) eof 547{ 548 return eof; 549} 550 551- (void) setEof:(id)theEOF 552{ 553 eof = theEOF; 554} 555 556@end 557