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