// [The "BSD licence"] // Copyright (c) 2006-2007 Kay Roepke 2010 Alan Condit // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // 3. The name of the author may not be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #import "ANTLRToken.h" #import "ANTLRCommonTokenStream.h" @implementation ANTLRCommonTokenStream @synthesize channelOverride; @synthesize channel; #pragma mark Initialization + (ANTLRCommonTokenStream *)newANTLRCommonTokenStream { return [[ANTLRCommonTokenStream alloc] init]; } + (ANTLRCommonTokenStream *)newANTLRCommonTokenStreamWithTokenSource:(id<ANTLRTokenSource>)theTokenSource { return [[ANTLRCommonTokenStream alloc] initWithTokenSource:(id<ANTLRTokenSource>)theTokenSource]; } + (ANTLRCommonTokenStream *)newANTLRCommonTokenStreamWithTokenSource:(id<ANTLRTokenSource>)theTokenSource Channel:(NSUInteger)aChannel { return [[ANTLRCommonTokenStream alloc] initWithTokenSource:(id<ANTLRTokenSource>)theTokenSource Channel:aChannel]; } - (id) init { if ((self = [super init]) != nil) { channelOverride = [[AMutableDictionary dictionaryWithCapacity:100] retain]; channel = ANTLRTokenChannelDefault; } return self; } - (id) initWithTokenSource:(id<ANTLRTokenSource>)theTokenSource { if ((self = [super initWithTokenSource:theTokenSource]) != nil) { channelOverride = [[AMutableDictionary dictionaryWithCapacity:100] retain]; channel = ANTLRTokenChannelDefault; } return self; } - (id) initWithTokenSource:(id<ANTLRTokenSource>)theTokenSource Channel:(NSUInteger)aChannel { if ((self = [super initWithTokenSource:theTokenSource]) != nil) { channelOverride = [[AMutableDictionary dictionaryWithCapacity:100] retain]; channel = aChannel; } return self; } - (void) dealloc { #ifdef DEBUG_DEALLOC NSLog( @"called dealloc in ANTLRCommonTokenStream" ); #endif if ( channelOverride ) [channelOverride release]; if ( tokens ) [tokens release]; [self setTokenSource:nil]; [super dealloc]; } /** Always leave index on an on-channel token. */ - (void) consume { if (index == -1) [self setup]; index++; [self sync:index]; while ( ((ANTLRCommonToken *)[tokens objectAtIndex:index]).channel != channel ) { index++; [self sync:index]; } } #pragma mark Lookahead - (id<ANTLRToken>) LB:(NSInteger)k { if ( k == 0 || (index-k) < 0 ) { return nil; } int i = index; int n = 1; // find k good tokens looking backwards while ( n <= k ) { i = [self skipOffChannelTokensReverse:i-1]; n++; } if ( i < 0 ) { return nil; } return [tokens objectAtIndex:i]; } - (id<ANTLRToken>) LT:(NSInteger)k { if ( index == -1 ) [self setup]; if ( k == 0 ) return nil; if ( k < 0 ) return [self LB:-k]; int i = index; int n = 1; while ( n < k ) { i = [self skipOffChannelTokens:i+1]; n++; } // if ( i >= (NSInteger)[tokens count] ) { // return [ANTLRCommonToken eofToken]; // } if ( i > range ) range = i; return [tokens objectAtIndex:i]; } #pragma mark Channels & Skipping - (NSInteger) skipOffChannelTokens:(NSInteger) idx { [self sync:idx]; while ( ((ANTLRCommonToken *)[tokens objectAtIndex:idx]).channel != channel ) { idx++; [self sync:idx]; } return idx; } - (NSInteger) skipOffChannelTokensReverse:(NSInteger) i { while ( i >= 0 && ((ANTLRCommonToken *)[tokens objectAtIndex:i]).channel != channel ) { i--; } return i; } - (void) setup { index = 0; [self sync:0]; int i = 0; while ( ((ANTLRCommonToken *)[tokens objectAtIndex:i]).channel != channel ) { i++; [self sync:i]; } // leave index pointing at first token on channel index = i; } - (NSInteger) getNumberOfOnChannelTokens { NSInteger n = 0; [self fill]; for( int i = 0; i < [tokens count]; i++ ) { ANTLRCommonToken *t = [tokens objectAtIndex:i]; if ( t.channel == channel ) n++; if ( t.type == ANTLRTokenTypeEOF ) break; } return n; } /** Reset this token stream by setting its token source. */ - (void) setTokenSource:(id<ANTLRTokenSource>)aTokenSource { [super setTokenSource:aTokenSource]; channel = ANTLRTokenChannelDefault; } - (id) copyWithZone:(NSZone *)aZone { ANTLRCommonTokenStream *copy; // copy = [[[self class] allocWithZone:aZone] init]; copy = [super copyWithZone:aZone]; // allocation occurs in ANTLRBaseTree if ( self.channelOverride ) copy.channelOverride = [channelOverride copyWithZone:aZone]; copy.channel = channel; return copy; } - (NSUInteger)channel { return channel; } - (void)setChannel:(NSUInteger)aChannel { channel = aChannel; } - (AMutableDictionary *)channelOverride { return channelOverride; } - (void)setChannelOverride:(AMutableDictionary *)anOverride { channelOverride = anOverride; } #ifdef DONTUSENOMO #pragma mark Token access - (NSArray *) tokensInRange:(NSRange)aRange { return [tokens subarrayWithRange:aRange]; } #pragma mark Accessors - (id<ANTLRTokenSource>) getTokenSource { return tokenSource; } - (NSArray *) tokensInRange:(NSRange)aRange inBitSet:(ANTLRBitSet *)aBitSet { unsigned int startIndex = aRange.location; unsigned int stopIndex = aRange.location+aRange.length; if ( index == -1 ) { [self setup]; } if (stopIndex >= [tokens count]) { stopIndex = [tokens count] - 1; } AMutableArray *filteredTokens = [AMutableArray arrayWithCapacity:100]; unsigned int i=0; for (i = startIndex; i<=stopIndex; i++) { id<ANTLRToken> token = [tokens objectAtIndex:i]; if (aBitSet == nil || [aBitSet member:token.type]) { [filteredTokens addObject:token]; } } if ([filteredTokens count]) { return filteredTokens; } else { [filteredTokens release]; return nil; } } - (NSArray *) tokensInRange:(NSRange)aRange withTypes:(NSArray *)tokenTypes { ANTLRBitSet *bits = [[ANTLRBitSet alloc] initWithArrayOfBits:tokenTypes]; NSArray *returnTokens = [[self tokensInRange:aRange inBitSet:bits] retain]; [bits release]; return returnTokens; } - (NSArray *) tokensInRange:(NSRange)aRange withType:(NSInteger)tokenType { ANTLRBitSet *bits = [[ANTLRBitSet alloc] init]; [bits add:tokenType]; NSArray *returnTokens = [[self tokensInRange:aRange inBitSet:bits] retain]; [bits release]; return returnTokens; } - (id<ANTLRToken>) getToken:(NSInteger)i { return [tokens objectAtIndex:i]; } - (NSInteger) size { return [tokens count]; } - (void) rewind { [self seek:lastMarker]; } - (void) rewind:(NSInteger)marker { [self seek:marker]; } - (void) seek:(NSInteger)anIndex { index = anIndex; } #pragma mark toString routines - (NSString *) toString { if ( index == -1 ) { [self setup]; } return [self toStringFromStart:0 ToEnd:[tokens count]]; } - (NSString *) toStringFromStart:(NSInteger)startIdx ToEnd:(NSInteger) stopIdx { NSMutableString *stringBuffer; id<ANTLRToken> t; if ( startIdx < 0 || stopIdx < 0 ) { return nil; } if ( index == -1 ) { [self setup]; } if ( stopIdx >= [tokens count] ) { stopIdx = [tokens count]-1; } stringBuffer = [NSMutableString stringWithCapacity:30]; for (int i = startIdx; i <= stopIdx; i++) { t = (id<ANTLRToken>)[tokens objectAtIndex:i]; [stringBuffer appendString:[t text]]; } return stringBuffer; } - (NSString *) toStringFromToken:(id<ANTLRToken>)startToken ToToken:(id<ANTLRToken>)stopToken { if (startToken && stopToken) { int startIdx = [startToken getTokenIndex]; int stopIdx = [stopToken getTokenIndex]; return [self toStringFromStart:startIdx ToEnd:stopIdx]; } return nil; } #endif @end