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.
203 lines
5.8 KiB
203 lines
5.8 KiB
//
|
|
// TreeIterator.m
|
|
// ANTLR
|
|
//
|
|
// Created by Ian Michell on 26/04/2010.
|
|
// Copyright (c) 2010 Ian Michell 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 "TreeIterator.h"
|
|
#import "CommonTreeAdaptor.h"
|
|
|
|
@implementation TreeIterator
|
|
|
|
+ (TreeIterator *) newANTRLTreeIterator
|
|
{
|
|
return [[TreeIterator alloc] init];
|
|
}
|
|
|
|
+ (TreeIterator *) newANTRLTreeIteratorWithAdaptor:(CommonTreeAdaptor *)adaptor
|
|
andTree:(id<BaseTree>)tree
|
|
{
|
|
return [[TreeIterator alloc] initWithTreeAdaptor:adaptor andTree:tree];
|
|
}
|
|
|
|
- (id) init
|
|
{
|
|
self = [super init];
|
|
if ( self != nil ) {
|
|
firstTime = YES;
|
|
nodes = [[FastQueue newFastQueue] retain];
|
|
down = [[adaptor createTree:TokenTypeDOWN Text:@"DOWN"] retain];
|
|
up = [[adaptor createTree:TokenTypeUP Text:@"UP"] retain];
|
|
eof = [[adaptor createTree:TokenTypeEOF Text:@"EOF"] retain];
|
|
tree = eof;
|
|
root = eof;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
-(id) initWithTree:(id<BaseTree>) t
|
|
{
|
|
self = [super init];
|
|
if ( self != nil ) {
|
|
firstTime = YES;
|
|
adaptor = [[CommonTreeAdaptor newTreeAdaptor] retain];
|
|
tree = [t retain];
|
|
root = t;
|
|
nodes = [[FastQueue newFastQueue] retain];
|
|
down = [[adaptor createTree:TokenTypeDOWN Text:@"DOWN"] retain];
|
|
up = [[adaptor createTree:TokenTypeUP Text:@"UP"] retain];
|
|
eof = [[adaptor createTree:TokenTypeEOF Text:@"EOF"] retain];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
-(id) initWithTreeAdaptor:(id<TreeAdaptor>)a andTree:(id<BaseTree>)t
|
|
{
|
|
self = [super init];
|
|
if ( self != nil ) {
|
|
firstTime = YES;
|
|
adaptor = [a retain];
|
|
tree = [t retain];
|
|
root = t;
|
|
nodes = [[FastQueue newFastQueue] retain];
|
|
down = [[adaptor createTree:TokenTypeDOWN Text:@"DOWN"] retain];
|
|
up = [[adaptor createTree:TokenTypeUP Text:@"UP"] retain];
|
|
eof = [[adaptor createTree:TokenTypeEOF Text:@"EOF"] retain];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
#ifdef DEBUG_DEALLOC
|
|
NSLog( @"called dealloc in TreeIterator" );
|
|
#endif
|
|
if ( adaptor ) [adaptor release];
|
|
if ( nodes ) [nodes release];
|
|
if ( tree && tree != eof ) [tree release];
|
|
if ( root && root != eof && root != tree ) [root release];
|
|
if ( down ) [down release];
|
|
if ( up ) [up release];
|
|
if ( eof ) [eof release];
|
|
[super dealloc];
|
|
}
|
|
|
|
- (void)reset
|
|
{
|
|
firstTime = YES;
|
|
tree = root;
|
|
[nodes clear];
|
|
}
|
|
|
|
-(BOOL) hasNext
|
|
{
|
|
if ( firstTime ) {
|
|
return root != nil;
|
|
}
|
|
if ( nodes && [nodes size] > 0) {
|
|
return YES;
|
|
}
|
|
if ( tree == nil ) {
|
|
return NO;
|
|
}
|
|
if ( [adaptor getChildCount:tree] > 0 ) {
|
|
return YES;
|
|
}
|
|
return [adaptor getParent:tree] != nil;
|
|
}
|
|
|
|
-(id) nextObject
|
|
{
|
|
// is this the first time we are using this method?
|
|
if ( firstTime ) {
|
|
firstTime = NO;
|
|
if ( [adaptor getChildCount:tree] == 0 ) {
|
|
[nodes addObject:eof];
|
|
return tree;
|
|
}
|
|
return tree;
|
|
}
|
|
// do we have any objects queued up?
|
|
if ( nodes && [nodes size] > 0 ) {
|
|
return [nodes remove];
|
|
}
|
|
// no nodes left?
|
|
if ( tree == nil ) {
|
|
return eof;
|
|
}
|
|
if ( [adaptor getChildCount:tree] > 0 ) {
|
|
tree = [adaptor getChild:tree At:0];
|
|
[nodes addObject:tree]; // real node is next after down
|
|
return self.down;
|
|
}
|
|
// if no children, look for next sibling of ancestor
|
|
id<BaseTree> parent = [adaptor getParent:tree];
|
|
while (parent != nil && ([adaptor getChildIndex:tree] + 1) >= [adaptor getChildCount:parent]) {
|
|
[nodes addObject:up];
|
|
tree = parent;
|
|
parent = [adaptor getParent:tree];
|
|
}
|
|
if ( parent == nil ) {
|
|
tree = nil;
|
|
[nodes addObject:self.eof];
|
|
return [nodes remove];
|
|
}
|
|
// must have found a node with an unvisited sibling
|
|
// move to it and return it
|
|
NSInteger nextSiblingIndex = [adaptor getChildIndex:tree] + 1;
|
|
tree = [adaptor getChild:parent At:nextSiblingIndex];
|
|
[nodes addObject:tree];
|
|
return [nodes remove];
|
|
}
|
|
|
|
-(NSArray *) allObjects
|
|
{
|
|
AMutableArray *array = [AMutableArray arrayWithCapacity:10];
|
|
while ( [self hasNext] ) {
|
|
[array addObject:[self nextObject]];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
- (void)remove
|
|
{
|
|
@throw [RuntimeException newException:@"UnsupportedOperationException"];
|
|
}
|
|
|
|
@synthesize firstTime;
|
|
@synthesize adaptor;
|
|
@synthesize root;
|
|
@synthesize tree;
|
|
@synthesize nodes;
|
|
|
|
@synthesize up;
|
|
@synthesize down;
|
|
@synthesize eof;
|
|
|
|
@end
|