blob: 9ebc325a0ec93b43f0fc676c5b0a8584ee39eaaf [file] [log] [blame]
// [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