blob: 68c1fc17aa33a31ca01bf34c44fdbf017a62962b [file] [log] [blame]
// [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