1*16467b97STreehugger Robot// [The "BSD licence"] 2*16467b97STreehugger Robot// Copyright (c) 2006-2007 Kay Roepke 2010 Alan Condit 3*16467b97STreehugger Robot// All rights reserved. 4*16467b97STreehugger Robot// 5*16467b97STreehugger Robot// Redistribution and use in source and binary forms, with or without 6*16467b97STreehugger Robot// modification, are permitted provided that the following conditions 7*16467b97STreehugger Robot// are met: 8*16467b97STreehugger Robot// 1. Redistributions of source code must retain the above copyright 9*16467b97STreehugger Robot// notice, this list of conditions and the following disclaimer. 10*16467b97STreehugger Robot// 2. Redistributions in binary form must reproduce the above copyright 11*16467b97STreehugger Robot// notice, this list of conditions and the following disclaimer in the 12*16467b97STreehugger Robot// documentation and/or other materials provided with the distribution. 13*16467b97STreehugger Robot// 3. The name of the author may not be used to endorse or promote products 14*16467b97STreehugger Robot// derived from this software without specific prior written permission. 15*16467b97STreehugger Robot// 16*16467b97STreehugger Robot// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17*16467b97STreehugger Robot// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18*16467b97STreehugger Robot// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19*16467b97STreehugger Robot// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20*16467b97STreehugger Robot// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21*16467b97STreehugger Robot// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22*16467b97STreehugger Robot// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23*16467b97STreehugger Robot// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24*16467b97STreehugger Robot// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25*16467b97STreehugger Robot// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26*16467b97STreehugger Robot 27*16467b97STreehugger Robot#import "Token.h" 28*16467b97STreehugger Robot#import "CommonTokenStream.h" 29*16467b97STreehugger Robot 30*16467b97STreehugger Robot 31*16467b97STreehugger Robot@implementation CommonTokenStream 32*16467b97STreehugger Robot 33*16467b97STreehugger Robot@synthesize channelOverride; 34*16467b97STreehugger Robot@synthesize channel; 35*16467b97STreehugger Robot 36*16467b97STreehugger Robot#pragma mark Initialization 37*16467b97STreehugger Robot 38*16467b97STreehugger Robot+ (CommonTokenStream *)newCommonTokenStream 39*16467b97STreehugger Robot{ 40*16467b97STreehugger Robot return [[CommonTokenStream alloc] init]; 41*16467b97STreehugger Robot} 42*16467b97STreehugger Robot 43*16467b97STreehugger Robot+ (CommonTokenStream *)newCommonTokenStreamWithTokenSource:(id<TokenSource>)theTokenSource 44*16467b97STreehugger Robot{ 45*16467b97STreehugger Robot return [[CommonTokenStream alloc] initWithTokenSource:(id<TokenSource>)theTokenSource]; 46*16467b97STreehugger Robot} 47*16467b97STreehugger Robot 48*16467b97STreehugger Robot+ (CommonTokenStream *)newCommonTokenStreamWithTokenSource:(id<TokenSource>)theTokenSource Channel:(NSUInteger)aChannel 49*16467b97STreehugger Robot{ 50*16467b97STreehugger Robot return [[CommonTokenStream alloc] initWithTokenSource:(id<TokenSource>)theTokenSource Channel:aChannel]; 51*16467b97STreehugger Robot} 52*16467b97STreehugger Robot 53*16467b97STreehugger Robot- (id) init 54*16467b97STreehugger Robot{ 55*16467b97STreehugger Robot if ((self = [super init]) != nil) { 56*16467b97STreehugger Robot channelOverride = [[AMutableDictionary dictionaryWithCapacity:100] retain]; 57*16467b97STreehugger Robot channel = TokenChannelDefault; 58*16467b97STreehugger Robot } 59*16467b97STreehugger Robot return self; 60*16467b97STreehugger Robot} 61*16467b97STreehugger Robot 62*16467b97STreehugger Robot- (id) initWithTokenSource:(id<TokenSource>)theTokenSource 63*16467b97STreehugger Robot{ 64*16467b97STreehugger Robot if ((self = [super initWithTokenSource:theTokenSource]) != nil) { 65*16467b97STreehugger Robot channelOverride = [[AMutableDictionary dictionaryWithCapacity:100] retain]; 66*16467b97STreehugger Robot channel = TokenChannelDefault; 67*16467b97STreehugger Robot } 68*16467b97STreehugger Robot return self; 69*16467b97STreehugger Robot} 70*16467b97STreehugger Robot 71*16467b97STreehugger Robot- (id) initWithTokenSource:(id<TokenSource>)theTokenSource Channel:(NSUInteger)aChannel 72*16467b97STreehugger Robot{ 73*16467b97STreehugger Robot if ((self = [super initWithTokenSource:theTokenSource]) != nil) { 74*16467b97STreehugger Robot channelOverride = [[AMutableDictionary dictionaryWithCapacity:100] retain]; 75*16467b97STreehugger Robot channel = aChannel; 76*16467b97STreehugger Robot } 77*16467b97STreehugger Robot return self; 78*16467b97STreehugger Robot} 79*16467b97STreehugger Robot 80*16467b97STreehugger Robot- (void) dealloc 81*16467b97STreehugger Robot{ 82*16467b97STreehugger Robot#ifdef DEBUG_DEALLOC 83*16467b97STreehugger Robot NSLog( @"called dealloc in CommonTokenStream" ); 84*16467b97STreehugger Robot#endif 85*16467b97STreehugger Robot if ( channelOverride ) [channelOverride release]; 86*16467b97STreehugger Robot if ( tokens ) [tokens release]; 87*16467b97STreehugger Robot [self setTokenSource:nil]; 88*16467b97STreehugger Robot [super dealloc]; 89*16467b97STreehugger Robot} 90*16467b97STreehugger Robot 91*16467b97STreehugger Robot/** Always leave index on an on-channel token. */ 92*16467b97STreehugger Robot- (void) consume 93*16467b97STreehugger Robot{ 94*16467b97STreehugger Robot if (index == -1) [self setup]; 95*16467b97STreehugger Robot index++; 96*16467b97STreehugger Robot [self sync:index]; 97*16467b97STreehugger Robot while ( ((CommonToken *)[tokens objectAtIndex:index]).channel != channel ) { 98*16467b97STreehugger Robot index++; 99*16467b97STreehugger Robot [self sync:index]; 100*16467b97STreehugger Robot } 101*16467b97STreehugger Robot} 102*16467b97STreehugger Robot 103*16467b97STreehugger Robot#pragma mark Lookahead 104*16467b97STreehugger Robot 105*16467b97STreehugger Robot- (id<Token>) LB:(NSInteger)k 106*16467b97STreehugger Robot{ 107*16467b97STreehugger Robot if ( k == 0 || (index-k) < 0 ) { 108*16467b97STreehugger Robot return nil; 109*16467b97STreehugger Robot } 110*16467b97STreehugger Robot int i = index; 111*16467b97STreehugger Robot int n = 1; 112*16467b97STreehugger Robot // find k good tokens looking backwards 113*16467b97STreehugger Robot while ( n <= k ) { 114*16467b97STreehugger Robot i = [self skipOffTokenChannelsReverse:i-1]; 115*16467b97STreehugger Robot n++; 116*16467b97STreehugger Robot } 117*16467b97STreehugger Robot if ( i < 0 ) { 118*16467b97STreehugger Robot return nil; 119*16467b97STreehugger Robot } 120*16467b97STreehugger Robot return [tokens objectAtIndex:i]; 121*16467b97STreehugger Robot} 122*16467b97STreehugger Robot 123*16467b97STreehugger Robot- (id<Token>) LT:(NSInteger)k 124*16467b97STreehugger Robot{ 125*16467b97STreehugger Robot if ( index == -1 ) [self setup]; 126*16467b97STreehugger Robot if ( k == 0 ) return nil; 127*16467b97STreehugger Robot if ( k < 0 ) return [self LB:-k]; 128*16467b97STreehugger Robot int i = index; 129*16467b97STreehugger Robot int n = 1; 130*16467b97STreehugger Robot while ( n < k ) { 131*16467b97STreehugger Robot i = [self skipOffTokenChannels:i+1]; 132*16467b97STreehugger Robot n++; 133*16467b97STreehugger Robot } 134*16467b97STreehugger Robot// if ( i >= (NSInteger)[tokens count] ) { 135*16467b97STreehugger Robot// return [CommonToken eofToken]; 136*16467b97STreehugger Robot// } 137*16467b97STreehugger Robot if ( i > range ) range = i; 138*16467b97STreehugger Robot return [tokens objectAtIndex:i]; 139*16467b97STreehugger Robot} 140*16467b97STreehugger Robot 141*16467b97STreehugger Robot#pragma mark Channels & Skipping 142*16467b97STreehugger Robot 143*16467b97STreehugger Robot- (NSInteger) skipOffTokenChannels:(NSInteger) idx 144*16467b97STreehugger Robot{ 145*16467b97STreehugger Robot [self sync:idx]; 146*16467b97STreehugger Robot while ( ((CommonToken *)[tokens objectAtIndex:idx]).channel != channel ) { 147*16467b97STreehugger Robot idx++; 148*16467b97STreehugger Robot [self sync:idx]; 149*16467b97STreehugger Robot } 150*16467b97STreehugger Robot return idx; 151*16467b97STreehugger Robot} 152*16467b97STreehugger Robot 153*16467b97STreehugger Robot- (NSInteger) skipOffTokenChannelsReverse:(NSInteger) i 154*16467b97STreehugger Robot{ 155*16467b97STreehugger Robot while ( i >= 0 && ((CommonToken *)[tokens objectAtIndex:i]).channel != channel ) { 156*16467b97STreehugger Robot i--; 157*16467b97STreehugger Robot } 158*16467b97STreehugger Robot return i; 159*16467b97STreehugger Robot} 160*16467b97STreehugger Robot 161*16467b97STreehugger Robot- (void) reset 162*16467b97STreehugger Robot{ 163*16467b97STreehugger Robot [super reset]; 164*16467b97STreehugger Robot index = [self skipOffTokenChannels:0]; 165*16467b97STreehugger Robot} 166*16467b97STreehugger Robot 167*16467b97STreehugger Robot- (void) setup 168*16467b97STreehugger Robot{ 169*16467b97STreehugger Robot index = 0; 170*16467b97STreehugger Robot [self sync:0]; 171*16467b97STreehugger Robot int i = 0; 172*16467b97STreehugger Robot while ( ((CommonToken *)[tokens objectAtIndex:i]).channel != channel ) { 173*16467b97STreehugger Robot i++; 174*16467b97STreehugger Robot [self sync:i]; 175*16467b97STreehugger Robot } 176*16467b97STreehugger Robot // leave index pointing at first token on channel 177*16467b97STreehugger Robot index = i; 178*16467b97STreehugger Robot} 179*16467b97STreehugger Robot 180*16467b97STreehugger Robot- (NSInteger) getNumberOfOnChannelTokens 181*16467b97STreehugger Robot{ 182*16467b97STreehugger Robot NSInteger n = 0; 183*16467b97STreehugger Robot [self fill]; 184*16467b97STreehugger Robot for( int i = 0; i < [tokens count]; i++ ) { 185*16467b97STreehugger Robot CommonToken *t = [tokens objectAtIndex:i]; 186*16467b97STreehugger Robot if ( t.channel == channel ) 187*16467b97STreehugger Robot n++; 188*16467b97STreehugger Robot if ( t.type == TokenTypeEOF ) 189*16467b97STreehugger Robot break; 190*16467b97STreehugger Robot } 191*16467b97STreehugger Robot return n; 192*16467b97STreehugger Robot} 193*16467b97STreehugger Robot 194*16467b97STreehugger Robot/** Reset this token stream by setting its token source. */ 195*16467b97STreehugger Robot- (void) setTokenSource:(id<TokenSource>)aTokenSource 196*16467b97STreehugger Robot{ 197*16467b97STreehugger Robot [super setTokenSource:aTokenSource]; 198*16467b97STreehugger Robot channel = TokenChannelDefault; 199*16467b97STreehugger Robot} 200*16467b97STreehugger Robot 201*16467b97STreehugger Robot- (id) copyWithZone:(NSZone *)aZone 202*16467b97STreehugger Robot{ 203*16467b97STreehugger Robot CommonTokenStream *copy; 204*16467b97STreehugger Robot 205*16467b97STreehugger Robot // copy = [[[self class] allocWithZone:aZone] init]; 206*16467b97STreehugger Robot copy = [super copyWithZone:aZone]; // allocation occurs in BaseTree 207*16467b97STreehugger Robot if ( self.channelOverride ) 208*16467b97STreehugger Robot copy.channelOverride = [channelOverride copyWithZone:aZone]; 209*16467b97STreehugger Robot copy.channel = channel; 210*16467b97STreehugger Robot return copy; 211*16467b97STreehugger Robot} 212*16467b97STreehugger Robot 213*16467b97STreehugger Robot- (NSUInteger)channel 214*16467b97STreehugger Robot{ 215*16467b97STreehugger Robot return channel; 216*16467b97STreehugger Robot} 217*16467b97STreehugger Robot 218*16467b97STreehugger Robot- (void)setChannel:(NSUInteger)aChannel 219*16467b97STreehugger Robot{ 220*16467b97STreehugger Robot channel = aChannel; 221*16467b97STreehugger Robot} 222*16467b97STreehugger Robot 223*16467b97STreehugger Robot- (AMutableDictionary *)channelOverride 224*16467b97STreehugger Robot{ 225*16467b97STreehugger Robot return channelOverride; 226*16467b97STreehugger Robot} 227*16467b97STreehugger Robot 228*16467b97STreehugger Robot- (void)setChannelOverride:(AMutableDictionary *)anOverride 229*16467b97STreehugger Robot{ 230*16467b97STreehugger Robot channelOverride = anOverride; 231*16467b97STreehugger Robot} 232*16467b97STreehugger Robot 233*16467b97STreehugger Robot#ifdef DONTUSENOMO 234*16467b97STreehugger Robot#pragma mark Token access 235*16467b97STreehugger Robot 236*16467b97STreehugger Robot- (NSArray *) tokensInRange:(NSRange)aRange 237*16467b97STreehugger Robot{ 238*16467b97STreehugger Robot return [tokens subarrayWithRange:aRange]; 239*16467b97STreehugger Robot} 240*16467b97STreehugger Robot 241*16467b97STreehugger Robot#pragma mark Accessors 242*16467b97STreehugger Robot 243*16467b97STreehugger Robot- (id<TokenSource>) getTokenSource 244*16467b97STreehugger Robot{ 245*16467b97STreehugger Robot return tokenSource; 246*16467b97STreehugger Robot} 247*16467b97STreehugger Robot 248*16467b97STreehugger Robot- (NSArray *) tokensInRange:(NSRange)aRange inBitSet:(ANTLRBitSet *)aBitSet 249*16467b97STreehugger Robot{ 250*16467b97STreehugger Robot unsigned int startIndex = aRange.location; 251*16467b97STreehugger Robot unsigned int stopIndex = aRange.location+aRange.length; 252*16467b97STreehugger Robot if ( index == -1 ) { 253*16467b97STreehugger Robot [self setup]; 254*16467b97STreehugger Robot } 255*16467b97STreehugger Robot if (stopIndex >= [tokens count]) { 256*16467b97STreehugger Robot stopIndex = [tokens count] - 1; 257*16467b97STreehugger Robot } 258*16467b97STreehugger Robot AMutableArray *filteredTokens = [AMutableArray arrayWithCapacity:100]; 259*16467b97STreehugger Robot unsigned int i=0; 260*16467b97STreehugger Robot for (i = startIndex; i<=stopIndex; i++) { 261*16467b97STreehugger Robot id<Token> token = [tokens objectAtIndex:i]; 262*16467b97STreehugger Robot if (aBitSet == nil || [aBitSet member:token.type]) { 263*16467b97STreehugger Robot [filteredTokens addObject:token]; 264*16467b97STreehugger Robot } 265*16467b97STreehugger Robot } 266*16467b97STreehugger Robot if ([filteredTokens count]) { 267*16467b97STreehugger Robot return filteredTokens; 268*16467b97STreehugger Robot } else { 269*16467b97STreehugger Robot [filteredTokens release]; 270*16467b97STreehugger Robot return nil; 271*16467b97STreehugger Robot } 272*16467b97STreehugger Robot} 273*16467b97STreehugger Robot 274*16467b97STreehugger Robot- (NSArray *) tokensInRange:(NSRange)aRange withTypes:(NSArray *)tokenTypes 275*16467b97STreehugger Robot{ 276*16467b97STreehugger Robot ANTLRBitSet *bits = [[ANTLRBitSet alloc] initWithArrayOfBits:tokenTypes]; 277*16467b97STreehugger Robot NSArray *returnTokens = [[self tokensInRange:aRange inBitSet:bits] retain]; 278*16467b97STreehugger Robot [bits release]; 279*16467b97STreehugger Robot return returnTokens; 280*16467b97STreehugger Robot} 281*16467b97STreehugger Robot 282*16467b97STreehugger Robot- (NSArray *) tokensInRange:(NSRange)aRange withType:(NSInteger)tokenType 283*16467b97STreehugger Robot{ 284*16467b97STreehugger Robot ANTLRBitSet *bits = [[ANTLRBitSet alloc] init]; 285*16467b97STreehugger Robot [bits add:tokenType]; 286*16467b97STreehugger Robot NSArray *returnTokens = [[self tokensInRange:aRange inBitSet:bits] retain]; 287*16467b97STreehugger Robot [bits release]; 288*16467b97STreehugger Robot return returnTokens; 289*16467b97STreehugger Robot} 290*16467b97STreehugger Robot 291*16467b97STreehugger Robot- (id<Token>) getToken:(NSInteger)i 292*16467b97STreehugger Robot{ 293*16467b97STreehugger Robot return [tokens objectAtIndex:i]; 294*16467b97STreehugger Robot} 295*16467b97STreehugger Robot 296*16467b97STreehugger Robot- (NSInteger) size 297*16467b97STreehugger Robot{ 298*16467b97STreehugger Robot return [tokens count]; 299*16467b97STreehugger Robot} 300*16467b97STreehugger Robot 301*16467b97STreehugger Robot- (void) rewind 302*16467b97STreehugger Robot{ 303*16467b97STreehugger Robot [self seek:lastMarker]; 304*16467b97STreehugger Robot} 305*16467b97STreehugger Robot 306*16467b97STreehugger Robot- (void) rewind:(NSInteger)marker 307*16467b97STreehugger Robot{ 308*16467b97STreehugger Robot [self seek:marker]; 309*16467b97STreehugger Robot} 310*16467b97STreehugger Robot 311*16467b97STreehugger Robot- (void) seek:(NSInteger)anIndex 312*16467b97STreehugger Robot{ 313*16467b97STreehugger Robot index = anIndex; 314*16467b97STreehugger Robot} 315*16467b97STreehugger Robot#pragma mark toString routines 316*16467b97STreehugger Robot 317*16467b97STreehugger Robot- (NSString *) toString 318*16467b97STreehugger Robot{ 319*16467b97STreehugger Robot if ( index == -1 ) { 320*16467b97STreehugger Robot [self setup]; 321*16467b97STreehugger Robot } 322*16467b97STreehugger Robot return [self toStringFromStart:0 ToEnd:[tokens count]]; 323*16467b97STreehugger Robot} 324*16467b97STreehugger Robot 325*16467b97STreehugger Robot- (NSString *) toStringFromStart:(NSInteger)startIdx ToEnd:(NSInteger) stopIdx 326*16467b97STreehugger Robot{ 327*16467b97STreehugger Robot NSMutableString *stringBuffer; 328*16467b97STreehugger Robot id<Token> t; 329*16467b97STreehugger Robot 330*16467b97STreehugger Robot if ( startIdx < 0 || stopIdx < 0 ) { 331*16467b97STreehugger Robot return nil; 332*16467b97STreehugger Robot } 333*16467b97STreehugger Robot if ( index == -1 ) { 334*16467b97STreehugger Robot [self setup]; 335*16467b97STreehugger Robot } 336*16467b97STreehugger Robot if ( stopIdx >= [tokens count] ) { 337*16467b97STreehugger Robot stopIdx = [tokens count]-1; 338*16467b97STreehugger Robot } 339*16467b97STreehugger Robot stringBuffer = [NSMutableString stringWithCapacity:30]; 340*16467b97STreehugger Robot for (int i = startIdx; i <= stopIdx; i++) { 341*16467b97STreehugger Robot t = (id<Token>)[tokens objectAtIndex:i]; 342*16467b97STreehugger Robot [stringBuffer appendString:[t text]]; 343*16467b97STreehugger Robot } 344*16467b97STreehugger Robot return stringBuffer; 345*16467b97STreehugger Robot} 346*16467b97STreehugger Robot 347*16467b97STreehugger Robot- (NSString *) toStringFromToken:(id<Token>)startToken ToToken:(id<Token>)stopToken 348*16467b97STreehugger Robot{ 349*16467b97STreehugger Robot if (startToken && stopToken) { 350*16467b97STreehugger Robot int startIdx = [startToken getTokenIndex]; 351*16467b97STreehugger Robot int stopIdx = [stopToken getTokenIndex]; 352*16467b97STreehugger Robot return [self toStringFromStart:startIdx ToEnd:stopIdx]; 353*16467b97STreehugger Robot } 354*16467b97STreehugger Robot return nil; 355*16467b97STreehugger Robot} 356*16467b97STreehugger Robot#endif 357*16467b97STreehugger Robot 358*16467b97STreehugger Robot@end 359