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 "CommonTree.h" 28 29 30@implementation CommonTree 31 32+ (CommonTree *)INVALID_NODE 33{ 34 return [[CommonTree alloc] initWithToken:[CommonToken invalidToken]]; 35} 36 37+ (CommonTree *)invalidNode 38{ 39 // Had to cast to CommonTree * here, because GCC is dumb. 40 return [[CommonTree alloc] initWithToken:CommonToken.INVALID_TOKEN]; 41} 42 43+ (CommonTree *)newTree 44{ 45 return [[CommonTree alloc] init]; 46} 47 48+ (CommonTree *)newTreeWithTree:(CommonTree *)aTree 49{ 50 return [[CommonTree alloc] initWithTreeNode:aTree]; 51} 52 53+ (CommonTree *)newTreeWithToken:(id<Token>)aToken 54{ 55 return [[CommonTree alloc] initWithToken:aToken]; 56} 57 58+ (CommonTree *)newTreeWithTokenType:(NSInteger)aTType 59{ 60 return [[CommonTree alloc] initWithTokenType:(NSInteger)aTType]; 61} 62 63+ (CommonTree *)newTreeWithTokenType:(NSInteger)aTType Text:(NSString *)theText 64{ 65 return [[CommonTree alloc] initWithTokenType:(NSInteger)aTType Text:theText]; 66} 67 68- (id)init 69{ 70 self = (CommonTree *)[super init]; 71 if ( self != nil ) { 72 token = nil; 73 startIndex = -1; 74 stopIndex = -1; 75 parent = nil; 76 childIndex = -1; 77 } 78 return (CommonTree *)self; 79} 80 81- (id)initWithTreeNode:(CommonTree *)aNode 82{ 83 self = (CommonTree *)[super init]; 84 if ( self != nil ) { 85 token = aNode.token; 86 if ( token ) [token retain]; 87 startIndex = aNode.startIndex; 88 stopIndex = aNode.stopIndex; 89 parent = nil; 90 childIndex = -1; 91 } 92 return self; 93} 94 95- (id)initWithToken:(id<Token>)aToken 96{ 97 self = (CommonTree *)[super init]; 98 if ( self != nil ) { 99 token = aToken; 100 if ( token ) [token retain]; 101 startIndex = -1; 102 stopIndex = -1; 103 parent = nil; 104 childIndex = -1; 105 } 106 return self; 107} 108 109- (id)initWithTokenType:(NSInteger)aTokenType 110{ 111 self = (CommonTree *)[super init]; 112 if ( self != nil ) { 113 token = [[CommonToken newToken:aTokenType] retain]; 114// startIndex = token.startIndex; 115 startIndex = -1; 116// stopIndex = token.stopIndex; 117 stopIndex = -1; 118 parent = nil; 119 childIndex = -1; 120 } 121 return self; 122} 123 124- (id) initWithTokenType:(NSInteger)aTokenType Text:(NSString *)theText 125{ 126 self = (CommonTree *)[super init]; 127 if ( self != nil ) { 128 token = [[CommonToken newToken:aTokenType Text:theText] retain]; 129// startIndex = token.startIndex; 130 startIndex = -1; 131// stopIndex = token.stopIndex; 132 stopIndex = -1; 133 parent = nil; 134 childIndex = -1; 135 } 136 return self; 137} 138 139- (void) dealloc 140{ 141 if ( token ) { 142 [token release]; 143 token = nil; 144 } 145 if ( parent ) { 146 [parent release]; 147 parent = nil; 148 } 149 [super dealloc]; 150} 151 152- (id) copyWithZone:(NSZone *)aZone 153{ 154 CommonTree *copy; 155 156 // copy = [[[self class] allocWithZone:aZone] init]; 157 copy = [super copyWithZone:aZone]; // allocation occurs in BaseTree 158 if ( self.token ) 159 copy.token = [self.token copyWithZone:aZone]; 160 copy.startIndex = startIndex; 161 copy.stopIndex = stopIndex; 162 copy.parent = (CommonTree *)[self.parent copyWithZone:aZone]; 163 copy.childIndex = childIndex; 164 return copy; 165} 166 167- (BOOL) isNil 168{ 169 return token == nil; 170} 171 172- (CommonToken *) getToken 173{ 174 return token; 175} 176 177- (void) setToken:(CommonToken *) aToken 178{ 179 if ( token != aToken ) { 180 if ( token ) [token release]; 181 [aToken retain]; 182 token = aToken; 183 } 184} 185 186- (CommonTree *) dupNode 187{ 188 return [CommonTree newTreeWithTree:self ]; 189} 190 191- (NSInteger)type 192{ 193 if (token) 194 return token.type; 195 return TokenTypeInvalid; 196} 197 198- (NSString *)text 199{ 200 if (token) 201 return token.text; 202 return nil; 203} 204 205- (NSUInteger)line 206{ 207 if (token) 208 return token.line; 209 return 0; 210} 211 212- (void) setLine:(NSUInteger)aLine 213{ 214 if (token) 215 token.line = aLine; 216} 217 218- (NSUInteger)charPositionInLine 219{ 220 if (token) 221 return token.charPositionInLine; 222 return 0; 223} 224 225- (void) setCharPositionInLine:(NSUInteger)pos 226{ 227 if (token) 228 token.charPositionInLine = pos; 229} 230 231- (NSInteger) getTokenStartIndex 232{ 233 if ( startIndex == -1 && token != nil ) { 234 return [token getTokenIndex]; 235 } 236 return startIndex; 237} 238 239- (void) setTokenStartIndex: (NSInteger) aStartIndex 240{ 241 startIndex = aStartIndex; 242} 243 244- (NSInteger) getTokenStopIndex 245{ 246 if ( stopIndex == -1 && token != nil ) { 247 return [token getTokenIndex]; 248 } 249 return stopIndex; 250} 251 252- (void) setTokenStopIndex: (NSInteger) aStopIndex 253{ 254 stopIndex = aStopIndex; 255} 256 257#ifdef DONTUSENOMO 258- (NSString *) treeDescription 259{ 260 if (children) { 261 NSMutableString *desc = [NSMutableString stringWithString:@"(^"]; 262 [desc appendString:[self description]]; 263 unsigned int childIdx; 264 for (childIdx = 0; childIdx < [children count]; childIdx++) { 265 [desc appendFormat:@"%@", [[children objectAtIndex:childIdx] treeDescription]]; 266 } 267 [desc appendString:@")"]; 268 return desc; 269 } else { 270 return [self description]; 271 } 272} 273#endif 274 275/** For every node in this subtree, make sure it's start/stop token's 276 * are set. Walk depth first, visit bottom up. Only updates nodes 277 * with at least one token index < 0. 278 */ 279- (void) setUnknownTokenBoundaries 280{ 281 if ( children == nil ) { 282 if ( startIndex < 0 || stopIndex < 0 ) { 283 startIndex = stopIndex = [token getTokenIndex]; 284 } 285 return; 286 } 287 for (NSUInteger i=0; i < [children count]; i++) { 288 [[children objectAtIndex:i] setUnknownTokenBoundaries]; 289 } 290 if ( startIndex >= 0 && stopIndex >= 0 ) 291 return; // already set 292 if ( [children count] > 0 ) { 293 CommonTree *firstChild = (CommonTree *)[children objectAtIndex:0]; 294 CommonTree *lastChild = (CommonTree *)[children objectAtIndex:[children count]-1]; 295 startIndex = [firstChild getTokenStartIndex]; 296 stopIndex = [lastChild getTokenStopIndex]; 297 } 298} 299 300- (NSInteger) getChildIndex 301{ 302 return childIndex; 303} 304 305- (CommonTree *) getParent 306{ 307 return parent; 308} 309 310- (void) setParent:(CommonTree *) t 311{ 312 parent = t; 313} 314 315- (void) setChildIndex:(NSInteger) anIndex 316{ 317 childIndex = anIndex; 318} 319 320- (NSString *) description 321{ 322 if ( [self isNil] ) { 323 return @"nil"; 324 } 325 if ( [self type] == TokenTypeInvalid ) { 326 return @"<errornode>"; 327 } 328 if ( token==nil ) { 329 return nil; 330 } 331 return token.text; 332} 333 334- (NSString *) toString 335{ 336 return [self description]; 337} 338 339@synthesize token; 340@synthesize startIndex; 341@synthesize stopIndex; 342@synthesize parent; 343@synthesize childIndex; 344 345@end 346