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 28#import "CommonToken.h" 29 30static CommonToken *SKIP_TOKEN; 31static CommonToken *EOF_TOKEN; 32static CommonToken *INVALID_TOKEN; 33 34@implementation CommonToken 35 36 static NSInteger DEFAULT_CHANNEL = TokenChannelDefault; 37 static NSInteger INVALID_TOKEN_TYPE = TokenTypeInvalid; 38 39 40@synthesize text; 41@synthesize type; 42@synthesize line; 43@synthesize charPositionInLine; 44@synthesize channel; 45@synthesize index; 46@synthesize startIndex; 47@synthesize stopIndex; 48@synthesize input; 49 50+ (void) initialize 51{ 52 EOF_TOKEN = [CommonToken newToken:TokenTypeEOF Text:@"EOF"]; 53 SKIP_TOKEN = [CommonToken newToken:TokenTypeInvalid Text:@"Skip"]; 54 INVALID_TOKEN = [CommonToken newToken:TokenTypeInvalid Text:@"Invalid"]; 55 [EOF_TOKEN retain]; 56 [SKIP_TOKEN retain]; 57 [INVALID_TOKEN retain]; 58} 59 60+ (CommonToken *)INVALID_TOKEN 61{ 62 return INVALID_TOKEN; 63} 64 65+ (NSInteger) DEFAULT_CHANNEL 66{ 67 return DEFAULT_CHANNEL; 68} 69 70+ (NSInteger) INVALID_TOKEN_TYPE 71{ 72 return INVALID_TOKEN_TYPE; 73} 74 75+ (CommonToken *) newToken 76{ 77 return [[CommonToken alloc] init]; 78} 79 80+ (CommonToken *) newToken:(id<CharStream>)anInput Type:(NSInteger)aTType Channel:(NSInteger)aChannel Start:(NSInteger)aStart Stop:(NSInteger)aStop 81{ 82 return [[CommonToken alloc] initWithInput:(id<CharStream>)anInput Type:(NSInteger)aTType Channel:(NSInteger)aChannel Start:(NSInteger)aStart Stop:(NSInteger)aStop]; 83} 84 85+ (CommonToken *) newToken:(TokenType)tokenType 86{ 87 return( [[CommonToken alloc] initWithType:tokenType] ); 88} 89 90+ (CommonToken *) newToken:(NSInteger)tokenType Text:(NSString *)tokenText 91{ 92 return( [[CommonToken alloc] initWithType:tokenType Text:tokenText] ); 93} 94 95+ (CommonToken *) newTokenWithToken:(CommonToken *)fromToken 96{ 97 return( [[CommonToken alloc] initWithToken:fromToken] ); 98} 99 100// return the singleton EOF Token 101+ (id<Token>) eofToken 102{ 103 if (EOF_TOKEN == nil) { 104 EOF_TOKEN = [[CommonToken newToken:TokenTypeEOF Text:@"EOF"] retain]; 105 } 106 return EOF_TOKEN; 107} 108 109// return the singleton skip Token 110+ (id<Token>) skipToken 111{ 112 if (SKIP_TOKEN == nil) { 113 SKIP_TOKEN = [[CommonToken newToken:TokenTypeInvalid Text:@"Skip"] retain]; 114 } 115 return SKIP_TOKEN; 116} 117 118// return the singleton skip Token 119+ (id<Token>) invalidToken 120{ 121 if (INVALID_TOKEN == nil) { 122 INVALID_TOKEN = [[CommonToken newToken:TokenTypeInvalid Text:@"Invalid"] retain]; 123 } 124 return SKIP_TOKEN; 125} 126 127// the default channel for this class of Tokens 128+ (TokenChannel) defaultChannel 129{ 130 return TokenChannelDefault; 131} 132 133- (id) init 134{ 135 if ((self = [super init]) != nil) { 136 input = nil; 137 type = TokenTypeInvalid; 138 channel = TokenChannelDefault; 139 startIndex = 0; 140 stopIndex = 0; 141 } 142 return self; 143} 144 145// designated initializer 146- (id) initWithInput:(id<CharStream>)anInput 147 Type:(NSInteger)aTType 148 Channel:(NSInteger)aChannel 149 Start:(NSInteger)aStart 150 Stop:(NSInteger)aStop 151{ 152 if ((self = [super init]) != nil) { 153 input = anInput; 154 if ( input ) [input retain]; 155 type = aTType; 156 channel = aChannel; 157 startIndex = aStart; 158 stopIndex = aStop; 159 if (type == TokenTypeEOF) 160 text = @"EOF"; 161 else 162 text = [input substringWithRange:NSMakeRange(startIndex, (stopIndex-startIndex)+1)]; 163 if ( text ) [text retain]; 164 } 165 return self; 166} 167 168- (id) initWithToken:(CommonToken *)oldToken 169{ 170 if ((self = [super init]) != nil) { 171 text = [NSString stringWithString:oldToken.text]; 172 if ( text ) [text retain]; 173 type = oldToken.type; 174 line = oldToken.line; 175 index = oldToken.index; 176 charPositionInLine = oldToken.charPositionInLine; 177 channel = oldToken.channel; 178 input = oldToken.input; 179 if ( input ) [input retain]; 180 if ( [oldToken isKindOfClass:[CommonToken class]] ) { 181 startIndex = oldToken.startIndex; 182 stopIndex = oldToken.stopIndex; 183 } 184 } 185 return self; 186} 187 188- (id) initWithType:(TokenType)aTType 189{ 190 if ((self = [super init]) != nil) { 191 self.type = aTType; 192 } 193 return self; 194} 195 196- (id) initWithType:(TokenType)aTType Text:(NSString *)tokenText 197{ 198 if ((self = [super init]) != nil) { 199 self.type = aTType; 200 self.text = [NSString stringWithString:tokenText]; 201 if ( text ) [text retain]; 202 } 203 return self; 204} 205 206- (void)dealloc 207{ 208#ifdef DEBUG_DEALLOC 209 NSLog( @"called dealloc in CommonToken" ); 210#endif 211 if ( input ) [input release]; 212 if ( text ) [text release]; 213 [super dealloc]; 214} 215 216// create a copy, including the text if available 217// the input stream is *not* copied! 218- (id) copyWithZone:(NSZone *)theZone 219{ 220 CommonToken *copy = [[[self class] allocWithZone:theZone] init]; 221 222 if (text) 223 copy.text = [text copyWithZone:nil]; 224 copy.type = type; 225 copy.line = line; 226 copy.charPositionInLine = charPositionInLine; 227 copy.channel = channel; 228 copy.index = index; 229 copy.startIndex = startIndex; 230 copy.stopIndex = stopIndex; 231 copy.input = input; 232 return copy; 233} 234 235 236//---------------------------------------------------------- 237// charPositionInLine 238//---------------------------------------------------------- 239- (NSUInteger) getCharPositionInLine 240{ 241 return charPositionInLine; 242} 243 244- (void) setCharPositionInLine:(NSUInteger)aCharPositionInLine 245{ 246 charPositionInLine = aCharPositionInLine; 247} 248 249//---------------------------------------------------------- 250// line 251//---------------------------------------------------------- 252- (NSUInteger) getLine 253{ 254 return line; 255} 256 257- (void) setLine:(NSUInteger)aLine 258{ 259 line = aLine; 260} 261 262//---------------------------------------------------------- 263// text 264//---------------------------------------------------------- 265- (NSString *) text 266{ 267 if (text != nil) { 268 return text; 269 } 270 if (input == nil) { 271 return nil; 272 } 273 int n = [input size]; 274 if ( startIndex < n && stopIndex < n) { 275 return [input substringWithRange:NSMakeRange(startIndex, (stopIndex-startIndex)+1)]; 276 } 277 else { 278 return @"<EOF>"; 279 } 280} 281 282- (void) setText:(NSString *)aText 283{ 284 if (text != aText) { 285 if ( text ) [text release]; 286 text = aText; 287 [text retain]; 288 } 289} 290 291 292//---------------------------------------------------------- 293// type 294//---------------------------------------------------------- 295- (NSInteger)type 296{ 297 return type; 298} 299 300- (void) setType:(NSInteger)aType 301{ 302 type = aType; 303} 304 305//---------------------------------------------------------- 306// channel 307//---------------------------------------------------------- 308- (NSUInteger)channel 309{ 310 return channel; 311} 312 313- (void) setChannel:(NSUInteger)aChannel 314{ 315 channel = aChannel; 316} 317 318 319//---------------------------------------------------------- 320// input 321//---------------------------------------------------------- 322- (id<CharStream>) input 323{ 324 return input; 325} 326 327- (void) setInput: (id<CharStream>) anInput 328{ 329 if (input != anInput) { 330 if ( input ) [input release]; 331 [anInput retain]; 332 } 333 input = anInput; 334} 335 336 337//---------------------------------------------------------- 338// start 339//---------------------------------------------------------- 340- (NSInteger) getStart 341{ 342 return startIndex; 343} 344 345- (void) setStart: (NSInteger) aStart 346{ 347 startIndex = aStart; 348} 349 350//---------------------------------------------------------- 351// stop 352//---------------------------------------------------------- 353- (NSInteger) getStop 354{ 355 return stopIndex; 356} 357 358- (void) setStop: (NSInteger) aStop 359{ 360 stopIndex = aStop; 361} 362 363//---------------------------------------------------------- 364// index 365//---------------------------------------------------------- 366- (NSInteger) getTokenIndex; 367{ 368 return index; 369} 370 371- (void) setTokenIndex: (NSInteger) aTokenIndex; 372{ 373 index = aTokenIndex; 374} 375 376 377// provide a textual representation for debugging 378- (NSString *) description 379{ 380 NSString *channelStr; 381 NSMutableString *txtString; 382 383 channelStr = @""; 384 if ( channel > 0 ) { 385 channelStr = [NSString stringWithFormat:@",channel=%d\n", channel]; 386 } 387 if ([self text] != nil) { 388 txtString = [NSMutableString stringWithString:[self text]]; 389 [txtString replaceOccurrencesOfString:@"\n" withString:@"\\\\n" options:NSAnchoredSearch range:NSMakeRange(0, [txtString length])]; 390 [txtString replaceOccurrencesOfString:@"\r" withString:@"\\\\r" options:NSAnchoredSearch range:NSMakeRange(0, [txtString length])]; 391 [txtString replaceOccurrencesOfString:@"\t" withString:@"\\\\t" options:NSAnchoredSearch range:NSMakeRange(0, [txtString length])]; 392 } else { 393 txtString = [NSMutableString stringWithString:@"<no text>"]; 394 } 395 return [NSString stringWithFormat:@"[@%d, %d:%d='%@',<%d>%@,%d:%d]", index, startIndex, stopIndex, txtString, type, channelStr, line, charPositionInLine]; 396} 397 398- (NSString *)toString 399{ 400 return [self description]; 401} 402 403@end 404