| // [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 "ANTLRCommonTree.h" |
| |
| |
| @implementation ANTLRCommonTree |
| |
| + (ANTLRCommonTree *)INVALID_NODE |
| { |
| return [[ANTLRCommonTree alloc] initWithToken:[ANTLRCommonToken invalidToken]]; |
| } |
| |
| + (ANTLRCommonTree *)invalidNode |
| { |
| // Had to cast to ANTLRCommonTree * here, because GCC is dumb. |
| return [[ANTLRCommonTree alloc] initWithToken:ANTLRCommonToken.INVALID_TOKEN]; |
| } |
| |
| + (ANTLRCommonTree *)newTree |
| { |
| return [[ANTLRCommonTree alloc] init]; |
| } |
| |
| + (ANTLRCommonTree *)newTreeWithTree:(ANTLRCommonTree *)aTree |
| { |
| return [[ANTLRCommonTree alloc] initWithTreeNode:aTree]; |
| } |
| |
| + (ANTLRCommonTree *)newTreeWithToken:(id<ANTLRToken>)aToken |
| { |
| return [[ANTLRCommonTree alloc] initWithToken:aToken]; |
| } |
| |
| + (ANTLRCommonTree *)newTreeWithTokenType:(NSInteger)aTType |
| { |
| return [[ANTLRCommonTree alloc] initWithTokenType:(NSInteger)aTType]; |
| } |
| |
| + (ANTLRCommonTree *)newTreeWithTokenType:(NSInteger)aTType Text:(NSString *)theText |
| { |
| return [[ANTLRCommonTree alloc] initWithTokenType:(NSInteger)aTType Text:theText]; |
| } |
| |
| - (id)init |
| { |
| self = (ANTLRCommonTree *)[super init]; |
| if ( self != nil ) { |
| token = nil; |
| startIndex = -1; |
| stopIndex = -1; |
| parent = nil; |
| childIndex = -1; |
| } |
| return (ANTLRCommonTree *)self; |
| } |
| |
| - (id)initWithTreeNode:(ANTLRCommonTree *)aNode |
| { |
| self = (ANTLRCommonTree *)[super init]; |
| if ( self != nil ) { |
| token = aNode.token; |
| if ( token ) [token retain]; |
| startIndex = aNode.startIndex; |
| stopIndex = aNode.stopIndex; |
| parent = nil; |
| childIndex = -1; |
| } |
| return self; |
| } |
| |
| - (id)initWithToken:(id<ANTLRToken>)aToken |
| { |
| self = (ANTLRCommonTree *)[super init]; |
| if ( self != nil ) { |
| token = aToken; |
| if ( token ) [token retain]; |
| startIndex = -1; |
| stopIndex = -1; |
| parent = nil; |
| childIndex = -1; |
| } |
| return self; |
| } |
| |
| - (id)initWithTokenType:(NSInteger)aTokenType |
| { |
| self = (ANTLRCommonTree *)[super init]; |
| if ( self != nil ) { |
| token = [[ANTLRCommonToken newToken:aTokenType] retain]; |
| // startIndex = token.startIndex; |
| startIndex = -1; |
| // stopIndex = token.stopIndex; |
| stopIndex = -1; |
| parent = nil; |
| childIndex = -1; |
| } |
| return self; |
| } |
| |
| - (id) initWithTokenType:(NSInteger)aTokenType Text:(NSString *)theText |
| { |
| self = (ANTLRCommonTree *)[super init]; |
| if ( self != nil ) { |
| token = [[ANTLRCommonToken newToken:aTokenType Text:theText] retain]; |
| // startIndex = token.startIndex; |
| startIndex = -1; |
| // stopIndex = token.stopIndex; |
| stopIndex = -1; |
| parent = nil; |
| childIndex = -1; |
| } |
| return self; |
| } |
| |
| - (void) dealloc |
| { |
| if ( token ) { |
| [token release]; |
| token = nil; |
| } |
| if ( parent ) { |
| [parent release]; |
| parent = nil; |
| } |
| [super dealloc]; |
| } |
| |
| - (id) copyWithZone:(NSZone *)aZone |
| { |
| ANTLRCommonTree *copy; |
| |
| // copy = [[[self class] allocWithZone:aZone] init]; |
| copy = [super copyWithZone:aZone]; // allocation occurs in ANTLRBaseTree |
| if ( self.token ) |
| copy.token = [self.token copyWithZone:aZone]; |
| copy.startIndex = startIndex; |
| copy.stopIndex = stopIndex; |
| copy.parent = (ANTLRCommonTree *)[self.parent copyWithZone:aZone]; |
| copy.childIndex = childIndex; |
| return copy; |
| } |
| |
| - (BOOL) isNil |
| { |
| return token == nil; |
| } |
| |
| - (ANTLRCommonToken *) getToken |
| { |
| return token; |
| } |
| |
| - (void) setToken:(ANTLRCommonToken *) aToken |
| { |
| if ( token != aToken ) { |
| if ( token ) [token release]; |
| [aToken retain]; |
| token = aToken; |
| } |
| } |
| |
| - (ANTLRCommonTree *) dupNode |
| { |
| return [ANTLRCommonTree newTreeWithTree:self ]; |
| } |
| |
| - (NSInteger)type |
| { |
| if (token) |
| return token.type; |
| return ANTLRTokenTypeInvalid; |
| } |
| |
| - (NSString *)text |
| { |
| if (token) |
| return token.text; |
| return nil; |
| } |
| |
| - (NSUInteger)line |
| { |
| if (token) |
| return token.line; |
| return 0; |
| } |
| |
| - (void) setLine:(NSUInteger)aLine |
| { |
| if (token) |
| token.line = aLine; |
| } |
| |
| - (NSUInteger)charPositionInLine |
| { |
| if (token) |
| return token.charPositionInLine; |
| return 0; |
| } |
| |
| - (void) setCharPositionInLine:(NSUInteger)pos |
| { |
| if (token) |
| token.charPositionInLine = pos; |
| } |
| |
| - (NSInteger) getTokenStartIndex |
| { |
| if ( startIndex == -1 && token != nil ) { |
| return [token getTokenIndex]; |
| } |
| return startIndex; |
| } |
| |
| - (void) setTokenStartIndex: (NSInteger) aStartIndex |
| { |
| startIndex = aStartIndex; |
| } |
| |
| - (NSInteger) getTokenStopIndex |
| { |
| if ( stopIndex == -1 && token != nil ) { |
| return [token getTokenIndex]; |
| } |
| return stopIndex; |
| } |
| |
| - (void) setTokenStopIndex: (NSInteger) aStopIndex |
| { |
| stopIndex = aStopIndex; |
| } |
| |
| #ifdef DONTUSENOMO |
| - (NSString *) treeDescription |
| { |
| if (children) { |
| NSMutableString *desc = [NSMutableString stringWithString:@"(^"]; |
| [desc appendString:[self description]]; |
| unsigned int childIdx; |
| for (childIdx = 0; childIdx < [children count]; childIdx++) { |
| [desc appendFormat:@"%@", [[children objectAtIndex:childIdx] treeDescription]]; |
| } |
| [desc appendString:@")"]; |
| return desc; |
| } else { |
| return [self description]; |
| } |
| } |
| #endif |
| |
| /** For every node in this subtree, make sure it's start/stop token's |
| * are set. Walk depth first, visit bottom up. Only updates nodes |
| * with at least one token index < 0. |
| */ |
| - (void) setUnknownTokenBoundaries |
| { |
| if ( children == nil ) { |
| if ( startIndex<0 || stopIndex<0 ) { |
| startIndex = stopIndex = [token getTokenIndex]; |
| } |
| return; |
| } |
| for (NSUInteger i=0; i < [children count]; i++) { |
| [[children objectAtIndex:i] setUnknownTokenBoundaries]; |
| } |
| if ( startIndex >= 0 && stopIndex >= 0 ) |
| return; // already set |
| if ( [children count] > 0 ) { |
| ANTLRCommonTree *firstChild = (ANTLRCommonTree *)[children objectAtIndex:0]; |
| ANTLRCommonTree *lastChild = (ANTLRCommonTree *)[children objectAtIndex:[children count]-1]; |
| startIndex = [firstChild getTokenStartIndex]; |
| stopIndex = [lastChild getTokenStopIndex]; |
| } |
| } |
| |
| - (NSInteger) getChildIndex |
| { |
| return childIndex; |
| } |
| |
| - (ANTLRCommonTree *) getParent |
| { |
| return parent; |
| } |
| |
| - (void) setParent:(ANTLRCommonTree *) t |
| { |
| parent = t; |
| } |
| |
| - (void) setChildIndex:(NSInteger) anIndex |
| { |
| childIndex = anIndex; |
| } |
| |
| - (NSString *) description |
| { |
| return [self toString]; |
| } |
| |
| - (NSString *) toString |
| { |
| if ( [self isNil] ) { |
| return @"nil"; |
| } |
| if ( [self type] == ANTLRTokenTypeInvalid ) { |
| return @"<errornode>"; |
| } |
| if ( token==nil ) { |
| return nil; |
| } |
| return token.text; |
| } |
| |
| @synthesize token; |
| @synthesize startIndex; |
| @synthesize stopIndex; |
| @synthesize parent; |
| @synthesize childIndex; |
| |
| @end |