1// [The "BSD licence"] 2// Copyright (c) 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 "ANTLRBufferedTokenStream.h" 28#import "ANTLRTokenSource.h" 29#import "ANTLRCommonTreeAdaptor.h" 30#import "ANTLRRuntimeException.h" 31 32extern NSInteger debug; 33 34@implementation ANTLRBufferedTokenStream 35 36@synthesize tokenSource; 37@synthesize tokens; 38@synthesize lastMarker; 39@synthesize index; 40@synthesize range; 41 42+ (ANTLRBufferedTokenStream *) newANTLRBufferedTokenStream 43{ 44 return [[ANTLRBufferedTokenStream alloc] init]; 45} 46 47+ (ANTLRBufferedTokenStream *) newANTLRBufferedTokenStreamWith:(id<ANTLRTokenSource>)aSource 48{ 49 return [[ANTLRBufferedTokenStream alloc] initWithTokenSource:aSource]; 50} 51 52- (ANTLRBufferedTokenStream *) init 53{ 54 if ((self = [super init]) != nil) 55 { 56 tokenSource = nil; 57 tokens = [[AMutableArray arrayWithCapacity:1000] retain]; 58 index = -1; 59 range = -1; 60 } 61 return self; 62} 63 64-(id) initWithTokenSource:(id<ANTLRTokenSource>)aSource 65{ 66 if ((self = [super init]) != nil) 67 { 68 tokenSource = [aSource retain]; 69 tokens = [[AMutableArray arrayWithCapacity:1000] retain]; 70 index = -1; 71 range = -1; 72 } 73 return self; 74} 75 76- (id) copyWithZone:(NSZone *)aZone 77{ 78 ANTLRBufferedTokenStream *copy; 79 80 copy = [[[self class] allocWithZone:aZone] init]; 81 copy.tokenSource = self.tokenSource; 82 if ( self.tokens ) 83 copy.tokens = [tokens copyWithZone:aZone]; 84 copy.lastMarker = self.lastMarker; 85 copy.index = self.index; 86 copy.range = self.range; 87 return copy; 88} 89 90- (void)dealloc 91{ 92#ifdef DEBUG_DEALLOC 93 NSLog( @"called dealloc in ANTLRBufferedTokenStream" ); 94#endif 95 if ( tokens ) [tokens release]; 96 if ( tokenSource ) [tokenSource release]; 97 [super dealloc]; 98} 99 100- (NSUInteger)line 101{ 102 return ((ANTLRCommonToken *)[tokens objectAtIndex:index]).line; 103} 104 105- (NSUInteger)charPositionInLine 106{ 107 return ((ANTLRCommonToken *)[tokens objectAtIndex:index]).charPositionInLine; 108} 109 110- (id<ANTLRTokenSource>) getTokenSource 111{ 112 return tokenSource; 113} 114 115- (NSInteger) getRange 116{ 117 return range; 118} 119 120- (void) setRange:(NSInteger)anInt 121{ 122 range = anInt; 123} 124 125- (NSInteger) mark 126{ 127 if ( index == -1 ) { 128 [self setup]; 129// [self fill]; 130 } 131 lastMarker = self.index; 132 return lastMarker; 133} 134 135- (void) release:(NSInteger) marker 136{ 137 // no resources to release 138} 139 140- (void) rewind:(NSInteger) marker 141{ 142 [self seek:marker]; 143} 144 145- (void) rewind 146{ 147 [self seek:lastMarker]; 148} 149 150- (void) reset 151{ 152 index = 0; 153 lastMarker = 0; 154} 155 156- (void) seek:(NSInteger) anIndex 157{ 158 index = anIndex; 159} 160 161- (NSInteger) size 162{ 163 return [tokens count]; 164} 165 166/** Move the input pointer to the next incoming token. The stream 167 * must become active with LT(1) available. consume() simply 168 * moves the input pointer so that LT(1) points at the next 169 * input symbol. Consume at least one token. 170 * 171 * Walk past any token not on the channel the parser is listening to. 172 */ 173- (void) consume 174{ 175 if ( index == -1 ) { 176 [self setup]; 177// [self fill]; 178 } 179 index++; 180 [self sync:index]; 181} 182 183/** Make sure index i in tokens has a token. */ 184- (void) sync:(NSInteger) i 185{ 186 // how many more elements we need? 187 NSInteger n = (i - [tokens count]) + 1; 188 if (debug > 1) NSLog(@"[self sync:%d] needs %d\n", i, n); 189 if ( n > 0 ) 190 [self fetch:n]; 191} 192 193/** add n elements to buffer */ 194- (void) fetch:(NSInteger)n 195{ 196 for (NSInteger i=1; i <= n; i++) { 197 id<ANTLRToken> t = [tokenSource nextToken]; 198 [t setTokenIndex:[tokens count]]; 199 if (debug > 1) NSLog(@"adding %@ at index %d\n", [t text], [tokens count]); 200 [tokens addObject:t]; 201 if ( t.type == ANTLRTokenTypeEOF ) 202 break; 203 } 204} 205 206- (id<ANTLRToken>) getToken:(NSInteger) i 207{ 208 if ( i < 0 || i >= [tokens count] ) { 209 @throw [ANTLRNoSuchElementException newException:[NSString stringWithFormat:@"token index %d out of range 0..%d", i, [tokens count]-1]]; 210 } 211 return [tokens objectAtIndex:i]; 212} 213 214/** Get all tokens from start..stop inclusively */ 215- (AMutableArray *)getFrom:(NSInteger)startIndex To:(NSInteger)stopIndex 216{ 217 if ( startIndex < 0 || stopIndex < 0 ) 218 return nil; 219 if ( index == -1 ) { 220 [self setup]; 221// [self fill]; 222 } 223 AMutableArray *subset = [AMutableArray arrayWithCapacity:5]; 224 if ( stopIndex >= [tokens count] ) 225 stopIndex = [tokens count]-1; 226 for (NSInteger i = startIndex; i <= stopIndex; i++) { 227 id<ANTLRToken>t = [tokens objectAtIndex:i]; 228 if ( t.type == ANTLRTokenTypeEOF ) 229 break; 230 [subset addObject:t]; 231 } 232 return subset; 233} 234 235- (NSInteger) LA:(NSInteger)i 236{ 237 return [[self LT:i] type]; 238} 239 240- (id<ANTLRToken>) LB:(NSInteger)k 241{ 242 if ( (index - k) < 0 ) 243 return nil; 244 return [tokens objectAtIndex:(index-k)]; 245} 246 247- (id<ANTLRToken>) LT:(NSInteger)k 248{ 249 if ( index == -1 ) { 250 [self setup]; 251// [self fill]; 252 } 253 if ( k == 0 ) 254 return nil; 255 if ( k < 0 ) 256 return [self LB:-k]; 257 258 NSInteger i = index + k - 1; 259 [self sync:i]; 260 if ( i >= [tokens count] ) { // return EOF token 261 // EOF must be last token 262 return [tokens objectAtIndex:([tokens count]-1)]; 263 } 264 if ( i > range ) 265 range = i; 266 return [tokens objectAtIndex:i]; 267} 268 269- (void) setup 270{ 271 [self sync:0]; 272 index = 0; 273} 274 275/** Reset this token stream by setting its token source. */ 276- (void) setTokenSource:(id<ANTLRTokenSource>) aTokenSource 277{ 278 tokenSource = aTokenSource; 279 if ( [tokens count] ) 280 [tokens removeAllObjects]; 281 index = -1; 282} 283 284- (AMutableArray *)getTokens 285{ 286 return tokens; 287} 288 289- (AMutableArray *)getTokensFrom:(NSInteger) startIndex To:(NSInteger) stopIndex 290{ 291 return [self getTokensFrom:startIndex To:stopIndex With:(ANTLRBitSet *)nil]; 292} 293 294/** Given a start and stop index, return a List of all tokens in 295 * the token type BitSet. Return null if no tokens were found. This 296 * method looks at both on and off channel tokens. 297 */ 298- (AMutableArray *)getTokensFrom:(NSInteger)startIndex To:(NSInteger)stopIndex With:(ANTLRBitSet *)types 299{ 300 if ( index == -1 ) { 301 [self setup]; 302// [self fill]; 303 } 304 if ( stopIndex >= [tokens count] ) 305 stopIndex = [tokens count]-1; 306 if ( startIndex < 0 ) 307 startIndex = 0; 308 if ( startIndex > stopIndex ) 309 return nil; 310 311 // list = tokens[start:stop]:{Token t, t.getType() in types} 312 AMutableArray *filteredTokens = [AMutableArray arrayWithCapacity:5]; 313 for (NSInteger i = startIndex; i <= stopIndex; i++) { 314 id<ANTLRToken>t = [tokens objectAtIndex:i]; 315 if ( types == nil || [types member:t.type] ) { 316 [filteredTokens addObject:t]; 317 } 318 } 319 if ( [filteredTokens count] == 0 ) { 320 filteredTokens = nil; 321 } 322 return filteredTokens; 323} 324 325- (AMutableArray *)getTokensFrom:(NSInteger)startIndex To:(NSInteger)stopIndex WithType:(NSInteger)ttype 326{ 327 return [self getTokensFrom:startIndex To:stopIndex With:[ANTLRBitSet of:ttype]]; 328} 329 330- (AMutableArray *)getTokensFrom:(NSInteger)startIndex To:(NSInteger)stopIndex WithList:(AMutableArray *)types 331{ 332 return [self getTokensFrom:startIndex To:stopIndex With:[ANTLRBitSet newANTLRBitSetWithArray:types]]; 333} 334 335- (NSString *)getSourceName 336{ 337 return [tokenSource getSourceName]; 338} 339 340/** Grab *all* tokens from stream and return string */ 341- (NSString *) toString 342{ 343 if ( index == -1 ) { 344 [self setup]; 345 } 346 [self fill]; 347 return [self toStringFromStart:0 ToEnd:[tokens count]-1]; 348} 349 350- (NSString *) toStringFromStart:(NSInteger)startIdx ToEnd:(NSInteger)stopIdx 351{ 352 if ( startIdx < 0 || stopIdx < 0 ) 353 return nil; 354 if ( index == -1 ) { 355 [self setup]; 356 } 357 if ( stopIdx >= [tokens count] ) 358 stopIdx = [tokens count]-1; 359 NSMutableString *buf = [NSMutableString stringWithCapacity:5]; 360 for (NSInteger i = startIdx; i <= stopIdx; i++) { 361 id<ANTLRToken>t = [tokens objectAtIndex:i]; 362 if ( t.type == ANTLRTokenTypeEOF ) 363 break; 364 [buf appendString:[t text]]; 365 } 366 return buf; 367} 368 369- (NSString *) toStringFromToken:(id<ANTLRToken>)startToken ToToken:(id<ANTLRToken>)stopToken 370{ 371 if ( startToken != nil && stopToken != nil ) { 372 return [self toStringFromStart:[startToken getTokenIndex] ToEnd:[stopToken getTokenIndex]]; 373 } 374 return nil; 375} 376 377/** Get all tokens from lexer until EOF */ 378- (void) fill 379{ 380 if ( index == -1 ) [self setup]; 381 if ( [((ANTLRCommonToken *)[tokens objectAtIndex:index]) type] == ANTLRTokenTypeEOF ) 382 return; 383 384 NSInteger i = index+1; 385 [self sync:i]; 386 while ( [((ANTLRCommonToken *)[tokens objectAtIndex:i]) type] != ANTLRTokenTypeEOF ) { 387 i++; 388 [self sync:i]; 389 } 390} 391 392@end 393