ANTLRBufferedTreeNodeStream.m revision 324c4644fee44b9898524c09511bd33c3f12e2df
1//
2//  ANTLRBufferedTreeNodeStream.m
3//  ANTLR
4//
5// [The "BSD licence"]
6// Copyright (c) 2010 Ian Michell 2010 Alan Condit
7// All rights reserved.
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions
11// are met:
12// 1. Redistributions of source code must retain the above copyright
13//    notice, this list of conditions and the following disclaimer.
14// 2. Redistributions in binary form must reproduce the above copyright
15//    notice, this list of conditions and the following disclaimer in the
16//    documentation and/or other materials provided with the distribution.
17// 3. The name of the author may not be used to endorse or promote products
18//    derived from this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#import "ANTLRBufferedTreeNodeStream.h"
32#import "ANTLRStreamEnumerator.h"
33#import "ANTLRCommonTreeAdaptor.h"
34
35extern NSInteger debug;
36
37#ifdef DONTUSENOMO
38@implementation ANTLRTreeStreamIterator
39+ newANTLRTreeStreamIteratorWithNodes:(ANTLRBufferedTreeNodeStream *)theStream
40{
41    return[[ANTLRTreeStreamIterator alloc] initWithStream:theStream];
42}
43
44- (id) initWithStream:(ANTLRBufferedTreeNodeStream *)theStream
45{
46    if ((self = [super init]) != nil) {
47        idx = 0;
48        input = theStream;
49        nodes = [theStream getNodes];
50    }
51    return self;
52}
53
54- (BOOL) hasNext
55{
56    return idx < [nodes count];
57}
58
59- (id) next
60{
61    NSInteger current = idx;
62    idx++;
63    if (current < [nodes count]) {
64    }
65    return [nodes getEof];
66}
67
68- (void) remove
69{
70	@throw [ANTLRRuntimeException newException:@"cannot remove nodes from stream"];
71}
72
73@end
74#endif
75
76@implementation ANTLRBufferedTreeNodeStream
77
78@synthesize up;
79@synthesize down;
80@synthesize eof;
81@synthesize nodes;
82@synthesize root;
83@synthesize tokens;
84@synthesize adaptor;
85@synthesize uniqueNavigationNodes;
86@synthesize index;
87@synthesize lastMarker;
88@synthesize calls;
89@synthesize e;
90@synthesize currentSymbol;
91
92+ (ANTLRBufferedTreeNodeStream *) newANTLRBufferedTreeNodeStream:(ANTLRCommonTree *) aTree
93{
94    return [((ANTLRBufferedTreeNodeStream *)[ANTLRBufferedTreeNodeStream alloc]) initWithTree:(ANTLRCommonTree *)aTree];
95}
96
97+ (ANTLRBufferedTreeNodeStream *) newANTLRBufferedTreeNodeStream:(id<ANTLRTreeAdaptor>)adaptor Tree:(ANTLRCommonTree *)aTree
98{
99    return [[ANTLRBufferedTreeNodeStream alloc] initWithTreeAdaptor:adaptor Tree:(ANTLRCommonTree *)aTree];
100}
101
102+ (ANTLRBufferedTreeNodeStream *) newANTLRBufferedTreeNodeStream:(id<ANTLRTreeAdaptor>)adaptor Tree:(ANTLRCommonTree *)aTree withBufferSize:(NSInteger)initialBufferSize
103{
104    return [[ANTLRBufferedTreeNodeStream alloc] initWithTreeAdaptor:adaptor Tree:(ANTLRCommonTree *)aTree WithBufferSize:initialBufferSize];
105}
106
107-(ANTLRBufferedTreeNodeStream *) init
108{
109	self = [super init];
110	if (self) {
111		index = -1;
112		uniqueNavigationNodes = NO;
113        root = [[ANTLRCommonTree alloc] init];
114        //		tokens = tree;
115        adaptor = [[[ANTLRCommonTreeAdaptor alloc] init] retain];
116        nodes = [[AMutableArray arrayWithCapacity:DEFAULT_INITIAL_BUFFER_SIZE] retain];
117        down = [[adaptor createTree:ANTLRTokenTypeDOWN Text:@"DOWN"] retain];
118        up = [[adaptor createTree:ANTLRTokenTypeUP Text:@"UP"] retain];
119        eof = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain];
120    }
121	return self;
122}
123
124- (ANTLRBufferedTreeNodeStream *)initWithTree:(ANTLRCommonTree *) aTree
125{
126	self = [super init];
127	if (self) {
128		index = -1;
129		uniqueNavigationNodes = NO;
130        root = aTree;
131        //		tokens = aTree;
132        adaptor = [[[ANTLRCommonTreeAdaptor alloc] init] retain];
133        nodes = [[AMutableArray arrayWithCapacity:DEFAULT_INITIAL_BUFFER_SIZE] retain];
134        down = [[adaptor createTree:ANTLRTokenTypeDOWN Text:@"DOWN"] retain];
135        up = [[adaptor createTree:ANTLRTokenTypeUP Text:@"UP"] retain];
136        eof = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain];
137    }
138	return self;
139}
140
141-(ANTLRBufferedTreeNodeStream *) initWithTreeAdaptor:(ANTLRCommonTreeAdaptor *)anAdaptor Tree:(ANTLRCommonTree *)aTree
142{
143	self = [super init];
144	if (self) {
145		index = -1;
146		uniqueNavigationNodes = NO;
147        root = aTree;
148        //		tokens = aTree;
149        adaptor = [anAdaptor retain];
150        nodes = [[AMutableArray arrayWithCapacity:DEFAULT_INITIAL_BUFFER_SIZE] retain];
151        down = [[adaptor createTree:ANTLRTokenTypeDOWN Text:@"DOWN"] retain];
152        up = [[adaptor createTree:ANTLRTokenTypeUP Text:@"UP"] retain];
153        eof = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain];
154    }
155	return self;
156}
157
158-(ANTLRBufferedTreeNodeStream *) initWithTreeAdaptor:(ANTLRCommonTreeAdaptor *)anAdaptor Tree:(ANTLRCommonTree *)aTree WithBufferSize:(NSInteger)bufferSize
159{
160	self = [super init];
161	if (self) {
162        //		down = [adaptor createToken:ANTLRTokenTypeDOWN withText:@"DOWN"];
163        //		up = [adaptor createToken:ANTLRTokenTypeDOWN withText:@"UP"];
164        //		eof = [adaptor createToken:ANTLRTokenTypeDOWN withText:@"EOF"];
165		index = -1;
166		uniqueNavigationNodes = NO;
167        root = aTree;
168        //		tokens = aTree;
169        adaptor = [anAdaptor retain];
170        nodes = [[AMutableArray arrayWithCapacity:bufferSize] retain];
171        down = [[adaptor createTree:ANTLRTokenTypeDOWN Text:@"DOWN"] retain];
172        up = [[adaptor createTree:ANTLRTokenTypeUP Text:@"UP"] retain];
173        eof = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain];
174	}
175	return self;
176}
177
178- (void)dealloc
179{
180#ifdef DEBUG_DEALLOC
181    NSLog( @"called dealloc in ANTLRBufferedTreeNodeStream" );
182#endif
183    if ( adaptor ) [adaptor release];
184    if ( nodes ) [nodes release];
185    if ( root ) [root release];
186    if ( down ) [down release];
187    if ( up ) [up release];
188    if ( eof ) [eof release];
189	[super dealloc];
190}
191
192- (id) copyWithZone:(NSZone *)aZone
193{
194    ANTLRBufferedTreeNodeStream *copy;
195    
196    copy = [[[self class] allocWithZone:aZone] init];
197    if ( up )
198        copy.up = [up copyWithZone:aZone];
199    if ( down )
200        copy.down = [down copyWithZone:aZone];
201    if ( eof )
202        copy.eof = [eof copyWithZone:aZone];
203    if ( nodes )
204        copy.nodes = [nodes copyWithZone:aZone];
205    if ( root )
206        copy.root = [root copyWithZone:aZone];
207    if ( tokens )
208        copy.tokens = [tokens copyWithZone:aZone];
209    if ( adaptor )
210        copy.adaptor = [adaptor copyWithZone:aZone];
211    copy.uniqueNavigationNodes = self.uniqueNavigationNodes;
212    copy.index = self.index;
213    copy.lastMarker = self.lastMarker;
214    if ( calls )
215        copy.calls = [calls copyWithZone:aZone];
216    return copy;
217}
218
219// protected methods. DO NOT USE
220#pragma mark Protected Methods
221-(void) fillBuffer
222{
223	[self fillBufferWithTree:root];
224	// if (debug > 1) NSLog("revIndex=%@", tokenTypeToStreamIndexesMap);
225	index = 0; // buffer of nodes intialized now
226}
227
228-(void) fillBufferWithTree:(ANTLRCommonTree *) aTree
229{
230	BOOL empty = [adaptor isNil:aTree];
231	if (!empty) {
232		[nodes addObject:aTree];
233	}
234	NSInteger n = [adaptor getChildCount:aTree];
235	if (!empty && n > 0) {
236		[self addNavigationNode:ANTLRTokenTypeDOWN];
237	}
238	for (NSInteger c = 0; c < n; c++) {
239		id child = [adaptor getChild:aTree At:c];
240		[self fillBufferWithTree:child];
241	}
242	if (!empty && n > 0) {
243		[self addNavigationNode:ANTLRTokenTypeUP];
244	}
245}
246
247-(NSInteger) getNodeIndex:(ANTLRCommonTree *) node
248{
249	if (index == -1) {
250		[self fillBuffer];
251	}
252	for (NSUInteger i = 0; i < [nodes count]; i++) {
253		id t = [nodes objectAtIndex:i];
254		if (t == node) {
255			return i;
256		}
257	}
258	return -1;
259}
260
261-(void) addNavigationNode:(NSInteger) type
262{
263	id navNode = nil;
264	if (type == ANTLRTokenTypeDOWN) {
265		if (self.uniqueNavigationNodes) {
266			navNode = [adaptor createToken:ANTLRTokenTypeDOWN Text:@"DOWN"];
267		}
268		else {
269			navNode = down;
270		}
271
272	}
273	else {
274		if (self.uniqueNavigationNodes) {
275			navNode = [adaptor createToken:ANTLRTokenTypeUP Text:@"UP"];
276		}
277		else {
278			navNode = up;
279		}
280	}
281	[nodes addObject:navNode];
282}
283
284-(id) getNode:(NSUInteger) i
285{
286	if (index == -1) {
287		[self fillBuffer];
288	}
289	return [nodes objectAtIndex:i];
290}
291
292-(id) LT:(NSInteger) k
293{
294	if (index == -1) {
295		[self fillBuffer];
296	}
297	if (k == 0) {
298		return nil;
299	}
300	if (k < 0) {
301		return [self LB:-k];
302	}
303	if ((index + k - 1) >= [nodes count]) {
304		return eof;
305	}
306	return [nodes objectAtIndex:(index + k - 1)];
307}
308
309-(id) getCurrentSymbol
310{
311	return [self LT:1];
312}
313
314-(id) LB:(NSInteger) k
315{
316	if (k == 0) {
317		return nil;
318	}
319	if ((index - k) < 0) {
320		return nil;
321	}
322	return [nodes objectAtIndex:(index - k)];
323}
324
325- (ANTLRCommonTree *)getTreeSource
326{
327    return root;
328}
329
330-(NSString *)getSourceName
331{
332	return [[self getTokenStream] getSourceName];
333}
334
335- (id<ANTLRTokenStream>)getTokenStream
336{
337    return tokens;
338}
339
340- (void) setTokenStream:(id<ANTLRTokenStream>)newtokens
341{
342    tokens = newtokens;
343}
344
345- (id<ANTLRTreeAdaptor>)getTreeAdaptor
346{
347    return adaptor;
348}
349
350- (void) setTreeAdaptor:(id<ANTLRTreeAdaptor>)anAdaptor
351{
352    adaptor = anAdaptor;
353}
354
355- (BOOL)getUniqueNavigationNodes
356{
357    return uniqueNavigationNodes;
358}
359
360- (void) setUniqueNavigationNodes:(BOOL)aVal
361{
362    uniqueNavigationNodes = aVal;
363}
364
365-(void) consume
366{
367	if (index == -1) {
368		[self fillBuffer];
369	}
370	index++;
371}
372
373-(NSInteger) LA:(NSInteger) i
374{
375	return [adaptor getType:[self LT:i]];
376}
377
378-(NSInteger) mark
379{
380	if (index == -1) {
381		[self fillBuffer];
382	}
383	lastMarker = self.index;
384	return lastMarker;
385}
386
387-(void) release:(NSInteger) marker
388{
389	// do nothing
390}
391
392-(void) rewind:(NSInteger) marker
393{
394	[self seek:marker];
395}
396
397-(void) rewind
398{
399	[self seek:lastMarker];
400}
401
402-(void) seek:(NSInteger) i
403{
404	if (index == -1) {
405		[self fillBuffer];
406	}
407	index = i;
408}
409
410-(void) push:(NSInteger) i
411{
412	if (calls == nil) {
413		calls = [ANTLRIntArray newArrayWithLen:INITIAL_CALL_STACK_SIZE];
414	}
415	[calls push:index];
416	[self seek:i];
417}
418
419-(NSInteger) pop
420{
421	NSInteger ret = [calls pop];
422	[self seek:ret];
423	return ret;
424}
425
426-(void) reset
427{
428	index = 0;
429	lastMarker = 0;
430	if (calls != nil) {
431		[calls reset];
432	}
433}
434
435-(NSUInteger) count
436{
437	if (index == -1) {
438		[self fillBuffer];
439	}
440	return [nodes count];
441}
442
443-(NSUInteger) size
444{
445	return [self count];
446}
447
448-(NSEnumerator *) objectEnumerator
449{
450	if (e == nil) {
451		e = [[ANTLRStreamEnumerator alloc] initWithNodes:nodes andEOF:eof];
452	}
453	return e;
454}
455
456-(void) replaceChildren:(ANTLRCommonTree *) parent From:(NSInteger)startIdx To:(NSInteger)stopIdx With:(ANTLRCommonTree *)aTree
457{
458	if (parent != nil) {
459		[adaptor replaceChildren:parent From:startIdx To:stopIdx With:aTree];
460	}
461}
462
463-(NSString *) toTokenTypeString
464{
465	if (index == -1)
466	{
467		[self fillBuffer];
468	}
469	NSMutableString *buf = [NSMutableString stringWithCapacity:10];
470	for (NSUInteger i= 0; i < [nodes count]; i++) {
471		ANTLRCommonTree * aTree = (ANTLRCommonTree *)[self getNode:i];
472		[buf appendFormat:@" %d", [adaptor getType:aTree]];
473	}
474	return buf;
475}
476
477-(NSString *) toTokenString:(NSInteger)aStart ToEnd:(NSInteger)aStop
478{
479	if (index == -1) {
480		[self fillBuffer];
481	}
482	NSMutableString *buf = [NSMutableString stringWithCapacity:10];
483	for (NSUInteger i = aStart; i < [nodes count] && i <= aStop; i++) {
484		ANTLRCommonTree * t = (ANTLRCommonTree *)[self getNode:i];
485		[buf appendFormat:@" %d", [adaptor getType:t]];
486	}
487	return buf;
488}
489
490-(NSString *) toStringFromNode:(id)aStart ToNode:(id)aStop
491{
492	if (aStart == nil || aStop == nil) {
493		return nil;
494	}
495	if (index == -1) {
496		[self fillBuffer];
497	}
498	
499	// if we have a token stream, use that to dump text in order
500	if ([self getTokenStream] != nil) {
501		NSInteger beginTokenIndex = [adaptor getTokenStartIndex:aStart];
502		NSInteger endTokenIndex = [adaptor getTokenStopIndex:aStop];
503		
504		if ([adaptor getType:aStop] == ANTLRTokenTypeUP) {
505			endTokenIndex = [adaptor getTokenStopIndex:aStart];
506		}
507		else if ([adaptor getType:aStop] == ANTLRTokenTypeEOF) {
508			endTokenIndex = [self count] - 2; //don't use EOF
509		}
510        [tokens toStringFromStart:beginTokenIndex ToEnd:endTokenIndex];
511	}
512	// walk nodes looking for aStart
513	ANTLRCommonTree * aTree = nil;
514	NSUInteger i = 0;
515	for (; i < [nodes count]; i++) {
516		aTree = [nodes objectAtIndex:i];
517		if (aTree == aStart) {
518			break;
519		}
520	}
521	NSMutableString *buf = [NSMutableString stringWithCapacity:10];
522	aTree = [nodes objectAtIndex:i]; // why?
523	while (aTree != aStop) {
524		NSString *text = [adaptor getText:aTree];
525		if (text == nil) {
526			text = [NSString stringWithFormat:@" %d", [adaptor getType:aTree]];
527		}
528		[buf appendString:text];
529		i++;
530		aTree = [nodes objectAtIndex:i];
531	}
532	NSString *text = [adaptor getText:aStop];
533	if (text == nil) {
534		text = [NSString stringWithFormat:@" %d", [adaptor getType:aStop]];
535	}
536	[buf appendString:text];
537	return buf;
538}
539
540// getters and setters
541- (AMutableArray *) getNodes
542{
543    return nodes;
544}
545
546- (id) eof
547{
548    return eof;
549}
550
551- (void) setEof:(id)theEOF
552{
553    eof = theEOF;
554}
555
556@end
557