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 32 extern 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