| // [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 |