You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
359 lines
8.5 KiB
359 lines
8.5 KiB
// [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 "Token.h"
|
|
#import "CommonTokenStream.h"
|
|
|
|
|
|
@implementation CommonTokenStream
|
|
|
|
@synthesize channelOverride;
|
|
@synthesize channel;
|
|
|
|
#pragma mark Initialization
|
|
|
|
+ (CommonTokenStream *)newCommonTokenStream
|
|
{
|
|
return [[CommonTokenStream alloc] init];
|
|
}
|
|
|
|
+ (CommonTokenStream *)newCommonTokenStreamWithTokenSource:(id<TokenSource>)theTokenSource
|
|
{
|
|
return [[CommonTokenStream alloc] initWithTokenSource:(id<TokenSource>)theTokenSource];
|
|
}
|
|
|
|
+ (CommonTokenStream *)newCommonTokenStreamWithTokenSource:(id<TokenSource>)theTokenSource Channel:(NSUInteger)aChannel
|
|
{
|
|
return [[CommonTokenStream alloc] initWithTokenSource:(id<TokenSource>)theTokenSource Channel:aChannel];
|
|
}
|
|
|
|
- (id) init
|
|
{
|
|
if ((self = [super init]) != nil) {
|
|
channelOverride = [[AMutableDictionary dictionaryWithCapacity:100] retain];
|
|
channel = TokenChannelDefault;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (id) initWithTokenSource:(id<TokenSource>)theTokenSource
|
|
{
|
|
if ((self = [super initWithTokenSource:theTokenSource]) != nil) {
|
|
channelOverride = [[AMutableDictionary dictionaryWithCapacity:100] retain];
|
|
channel = TokenChannelDefault;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (id) initWithTokenSource:(id<TokenSource>)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 CommonTokenStream" );
|
|
#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 ( ((CommonToken *)[tokens objectAtIndex:index]).channel != channel ) {
|
|
index++;
|
|
[self sync:index];
|
|
}
|
|
}
|
|
|
|
#pragma mark Lookahead
|
|
|
|
- (id<Token>) 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 skipOffTokenChannelsReverse:i-1];
|
|
n++;
|
|
}
|
|
if ( i < 0 ) {
|
|
return nil;
|
|
}
|
|
return [tokens objectAtIndex:i];
|
|
}
|
|
|
|
- (id<Token>) 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 skipOffTokenChannels:i+1];
|
|
n++;
|
|
}
|
|
// if ( i >= (NSInteger)[tokens count] ) {
|
|
// return [CommonToken eofToken];
|
|
// }
|
|
if ( i > range ) range = i;
|
|
return [tokens objectAtIndex:i];
|
|
}
|
|
|
|
#pragma mark Channels & Skipping
|
|
|
|
- (NSInteger) skipOffTokenChannels:(NSInteger) idx
|
|
{
|
|
[self sync:idx];
|
|
while ( ((CommonToken *)[tokens objectAtIndex:idx]).channel != channel ) {
|
|
idx++;
|
|
[self sync:idx];
|
|
}
|
|
return idx;
|
|
}
|
|
|
|
- (NSInteger) skipOffTokenChannelsReverse:(NSInteger) i
|
|
{
|
|
while ( i >= 0 && ((CommonToken *)[tokens objectAtIndex:i]).channel != channel ) {
|
|
i--;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
- (void) reset
|
|
{
|
|
[super reset];
|
|
index = [self skipOffTokenChannels:0];
|
|
}
|
|
|
|
- (void) setup
|
|
{
|
|
index = 0;
|
|
[self sync:0];
|
|
int i = 0;
|
|
while ( ((CommonToken *)[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++ ) {
|
|
CommonToken *t = [tokens objectAtIndex:i];
|
|
if ( t.channel == channel )
|
|
n++;
|
|
if ( t.type == TokenTypeEOF )
|
|
break;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
/** Reset this token stream by setting its token source. */
|
|
- (void) setTokenSource:(id<TokenSource>)aTokenSource
|
|
{
|
|
[super setTokenSource:aTokenSource];
|
|
channel = TokenChannelDefault;
|
|
}
|
|
|
|
- (id) copyWithZone:(NSZone *)aZone
|
|
{
|
|
CommonTokenStream *copy;
|
|
|
|
// copy = [[[self class] allocWithZone:aZone] init];
|
|
copy = [super copyWithZone:aZone]; // allocation occurs in BaseTree
|
|
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<TokenSource>) 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<Token> 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<Token>) 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<Token> 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<Token>)[tokens objectAtIndex:i];
|
|
[stringBuffer appendString:[t text]];
|
|
}
|
|
return stringBuffer;
|
|
}
|
|
|
|
- (NSString *) toStringFromToken:(id<Token>)startToken ToToken:(id<Token>)stopToken
|
|
{
|
|
if (startToken && stopToken) {
|
|
int startIdx = [startToken getTokenIndex];
|
|
int stopIdx = [stopToken getTokenIndex];
|
|
return [self toStringFromStart:startIdx ToEnd:stopIdx];
|
|
}
|
|
return nil;
|
|
}
|
|
#endif
|
|
|
|
@end
|