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 30 static CommonToken *SKIP_TOKEN; 31 static CommonToken *EOF_TOKEN; 32 static 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