1 15 16 package javassist.compiler; 17 18 class Token { 19 public Token next = null; 20 public int tokenId; 21 22 public long longValue; 23 public double doubleValue; 24 public String textValue; 25 } 26 27 public class Lex implements TokenId { 28 private int lastChar; 29 private StringBuffer textBuffer; 30 private Token currentToken; 31 private Token lookAheadTokens; 32 33 private String input; 34 private int position, maxlen, lineNumber; 35 36 39 public Lex(String s) { 40 lastChar = -1; 41 textBuffer = new StringBuffer (); 42 currentToken = new Token(); 43 lookAheadTokens = null; 44 45 input = s; 46 position = 0; 47 maxlen = s.length(); 48 lineNumber = 0; 49 } 50 51 public int get() { 52 if (lookAheadTokens == null) 53 return get(currentToken); 54 else { 55 Token t; 56 currentToken = t = lookAheadTokens; 57 lookAheadTokens = lookAheadTokens.next; 58 return t.tokenId; 59 } 60 } 61 62 65 public int lookAhead() { 66 return lookAhead(0); 67 } 68 69 public int lookAhead(int i) { 70 Token tk = lookAheadTokens; 71 if (tk == null) { 72 lookAheadTokens = tk = currentToken; tk.next = null; 74 get(tk); 75 } 76 77 for (; i-- > 0; tk = tk.next) 78 if (tk.next == null) { 79 Token tk2; 80 tk.next = tk2 = new Token(); 81 get(tk2); 82 } 83 84 currentToken = tk; 85 return tk.tokenId; 86 } 87 88 public String getString() { 89 return currentToken.textValue; 90 } 91 92 public long getLong() { 93 return currentToken.longValue; 94 } 95 96 public double getDouble() { 97 return currentToken.doubleValue; 98 } 99 100 private int get(Token token) { 101 int t; 102 do { 103 t = readLine(token); 104 } while (t == '\n'); 105 token.tokenId = t; 106 return t; 107 } 108 109 private int readLine(Token token) { 110 int c = getNextNonWhiteChar(); 111 if(c < 0) 112 return c; 113 else if(c == '\n') { 114 ++lineNumber; 115 return '\n'; 116 } 117 else if (c == '\'') 118 return readCharConst(token); 119 else if (c == '"') 120 return readStringL(token); 121 else if ('0' <= c && c <= '9') 122 return readNumber(c, token); 123 else if(c == '.'){ 124 c = getc(); 125 if ('0' <= c && c <= '9') { 126 StringBuffer tbuf = textBuffer; 127 tbuf.setLength(0); 128 tbuf.append('.'); 129 return readDouble(tbuf, c, token); 130 } 131 else{ 132 ungetc(c); 133 return readSeparator('.'); 134 } 135 } 136 else if ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '_' 137 || c == '$') 138 return readIdentifier(c, token); 139 else 140 return readSeparator(c); 141 } 142 143 private int getNextNonWhiteChar() { 144 int c; 145 do { 146 c = getc(); 147 if (c == '/') { 148 c = getc(); 149 if (c == '/') 150 do { 151 c = getc(); 152 } while (c != '\n' && c != '\r' && c != -1); 153 else if (c == '*') 154 while (true) { 155 c = getc(); 156 if (c == -1) 157 break; 158 else if (c == '*') 159 if ((c = getc()) == '/') { 160 c = ' '; 161 break; 162 } 163 else 164 ungetc(c); 165 } 166 else { 167 ungetc(c); 168 c = '/'; 169 } 170 } 171 } while(isBlank(c)); 172 return c; 173 } 174 175 private int readCharConst(Token token) { 176 int c; 177 int value = 0; 178 while ((c = getc()) != '\'') 179 if (c == '\\') 180 value = readEscapeChar(); 181 else if (c < 0x20) { 182 if (c == '\n') 183 ++lineNumber; 184 185 return BadToken; 186 } 187 else 188 value = c; 189 190 token.longValue = value; 191 return CharConstant; 192 } 193 194 private int readEscapeChar() { 195 int c = getc(); 196 if (c == 'n') 197 c = '\n'; 198 else if (c == 't') 199 c = '\t'; 200 else if (c == 'r') 201 c = '\r'; 202 else if (c == 'f') 203 c = '\f'; 204 else if (c == '\n') 205 ++lineNumber; 206 207 return c; 208 } 209 210 private int readStringL(Token token) { 211 int c; 212 StringBuffer tbuf = textBuffer; 213 tbuf.setLength(0); 214 for (;;) { 215 while ((c = getc()) != '"') { 216 if (c == '\\') 217 c = readEscapeChar(); 218 else if (c == '\n' || c < 0) { 219 ++lineNumber; 220 return BadToken; 221 } 222 223 tbuf.append((char)c); 224 } 225 226 for (;;) { 227 c = getc(); 228 if (c == '\n') 229 ++lineNumber; 230 else if (!isBlank(c)) 231 break; 232 } 233 234 if (c != '"') { 235 ungetc(c); 236 break; 237 } 238 } 239 240 token.textValue = tbuf.toString(); 241 return StringL; 242 } 243 244 private int readNumber(int c, Token token) { 245 long value = 0; 246 int c2 = getc(); 247 if (c == '0') 248 if (c2 == 'X' || c2 == 'x') 249 for (;;) { 250 c = getc(); 251 if ('0' <= c && c <= '9') 252 value = value * 16 + (long)(c - '0'); 253 else if ('A' <= c && c <= 'F') 254 value = value * 16 + (long)(c - 'A' + 10); 255 else if ('a' <= c && c <= 'f') 256 value = value * 16 + (long)(c - 'a' + 10); 257 else { 258 token.longValue = value; 259 if (c == 'L' || c == 'l') 260 return LongConstant; 261 else { 262 ungetc(c); 263 return IntConstant; 264 } 265 } 266 } 267 else if ('0' <= c2 && c2 <= '7') { 268 value = c2 - '0'; 269 for (;;) { 270 c = getc(); 271 if ('0' <= c && c <= '7') 272 value = value * 8 + (long)(c - '0'); 273 else { 274 token.longValue = value; 275 if (c == 'L' || c == 'l') 276 return LongConstant; 277 else { 278 ungetc(c); 279 return IntConstant; 280 } 281 } 282 } 283 } 284 285 value = c - '0'; 286 while ('0' <= c2 && c2 <= '9') { 287 value = value * 10 + c2 - '0'; 288 c2 = getc(); 289 } 290 291 token.longValue = value; 292 if (c2 == 'F' || c2 == 'f') { 293 token.doubleValue = (double)value; 294 return FloatConstant; 295 } 296 else if (c2 == 'E' || c2 == 'e' 297 || c2 == 'D' || c2 == 'd' || c2 == '.') { 298 StringBuffer tbuf = textBuffer; 299 tbuf.setLength(0); 300 tbuf.append(value); 301 return readDouble(tbuf, c2, token); 302 } 303 else if (c2 == 'L' || c2 == 'l') 304 return LongConstant; 305 else { 306 ungetc(c2); 307 return IntConstant; 308 } 309 } 310 311 private int readDouble(StringBuffer sbuf, int c, Token token) { 312 if (c != 'E' && c != 'e' && c != 'D' && c != 'd') { 313 sbuf.append((char)c); 314 for (;;) { 315 c = getc(); 316 if ('0' <= c && c <= '9') 317 sbuf.append((char)c); 318 else 319 break; 320 } 321 } 322 323 if (c == 'E' || c == 'e') { 324 sbuf.append((char)c); 325 c = getc(); 326 if (c == '+' || c == '-') { 327 sbuf.append((char)c); 328 c = getc(); 329 } 330 331 while ('0' <= c && c <= '9') { 332 sbuf.append((char)c); 333 c = getc(); 334 } 335 } 336 337 try { 338 token.doubleValue = Double.parseDouble(sbuf.toString()); 339 } 340 catch (NumberFormatException e) { 341 return BadToken; 342 } 343 344 if (c == 'F' || c == 'f') 345 return FloatConstant; 346 else { 347 if (c != 'D' && c != 'd') 348 ungetc(c); 349 350 return DoubleConstant; 351 } 352 } 353 354 private static final int[] equalOps 356 = { NEQ, 0, 0, 0, MOD_E, AND_E, 0, 0, 357 0, MUL_E, PLUS_E, 0, MINUS_E, 0, DIV_E, 0, 358 0, 0, 0, 0, 0, 0, 0, 0, 359 0, 0, 0, LE, EQ, GE, 0 }; 360 361 private int readSeparator(int c) { 362 int c2, c3; 363 if ('!' <= c && c <= '?') { 364 int t = equalOps[c - '!']; 365 if (t == 0) 366 return c; 367 else { 368 c2 = getc(); 369 if (c == c2) 370 switch (c) { 371 case '=' : 372 return EQ; 373 case '+' : 374 return PLUSPLUS; 375 case '-' : 376 return MINUSMINUS; 377 case '&' : 378 return ANDAND; 379 case '<' : 380 c3 = getc(); 381 if (c3 == '=') 382 return LSHIFT_E; 383 else { 384 ungetc(c3); 385 return LSHIFT; 386 } 387 case '>' : 388 c3 = getc(); 389 if (c3 == '=') 390 return RSHIFT_E; 391 else if (c3 == '>') { 392 c3 = getc(); 393 if (c3 == '=') 394 return ARSHIFT_E; 395 else { 396 ungetc(c3); 397 return ARSHIFT; 398 } 399 } 400 else { 401 ungetc(c3); 402 return RSHIFT; 403 } 404 default : 405 break; 406 } 407 else if (c2 == '=') 408 return t; 409 } 410 } 411 else if (c == '^') { 412 c2 = getc(); 413 if (c2 == '=') 414 return EXOR_E; 415 } 416 else if (c == '|') { 417 c2 = getc(); 418 if (c2 == '=') 419 return OR_E; 420 else if (c2 == '|') 421 return OROR; 422 } 423 else 424 return c; 425 426 ungetc(c2); 427 return c; 428 } 429 430 private int readIdentifier(int c, Token token) { 431 StringBuffer tbuf = textBuffer; 432 tbuf.setLength(0); 433 434 do { 435 tbuf.append((char)c); 436 c = getc(); 437 } while ('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '_' 438 || c == '$' || '0' <= c && c <= '9'); 439 440 ungetc(c); 441 442 String name = tbuf.toString(); 443 int t = ktable.lookup(name); 444 if (t >= 0) 445 return t; 446 else { 447 454 token.textValue = name; 455 return Identifier; 456 } 457 } 458 459 private static final KeywordTable ktable = new KeywordTable(); 460 461 static { 462 ktable.append("abstract", ABSTRACT); 463 ktable.append("boolean", BOOLEAN); 464 ktable.append("break", BREAK); 465 ktable.append("byte", BYTE); 466 ktable.append("case", CASE); 467 ktable.append("catch", CATCH); 468 ktable.append("char", CHAR); 469 ktable.append("class", CLASS); 470 ktable.append("const", CONST); 471 ktable.append("continue", CONTINUE); 472 ktable.append("default", DEFAULT); 473 ktable.append("do", DO); 474 ktable.append("double", DOUBLE); 475 ktable.append("else", ELSE); 476 ktable.append("extends", EXTENDS); 477 ktable.append("false", FALSE); 478 ktable.append("final", FINAL); 479 ktable.append("finally", FINALLY); 480 ktable.append("float", FLOAT); 481 ktable.append("for", FOR); 482 ktable.append("goto", GOTO); 483 ktable.append("if", IF); 484 ktable.append("implements", IMPLEMENTS); 485 ktable.append("import", IMPORT); 486 ktable.append("instanceof", INSTANCEOF); 487 ktable.append("int", INT); 488 ktable.append("interface", INTERFACE); 489 ktable.append("long", LONG); 490 ktable.append("native", NATIVE); 491 ktable.append("new", NEW); 492 ktable.append("null", NULL); 493 ktable.append("package", PACKAGE); 494 ktable.append("private", PRIVATE); 495 ktable.append("protected", PROTECTED); 496 ktable.append("public", PUBLIC); 497 ktable.append("return", RETURN); 498 ktable.append("short", SHORT); 499 ktable.append("static", STATIC); 500 ktable.append("strict", STRICT); 501 ktable.append("super", SUPER); 502 ktable.append("switch", SWITCH); 503 ktable.append("synchronized", SYNCHRONIZED); 504 ktable.append("this", THIS); 505 ktable.append("throw", THROW); 506 ktable.append("throws", THROWS); 507 ktable.append("transient", TRANSIENT); 508 ktable.append("true", TRUE); 509 ktable.append("try", TRY); 510 ktable.append("void", VOID); 511 ktable.append("volatile", VOLATILE); 512 ktable.append("while", WHILE); 513 } 514 515 private static boolean isBlank(int c) { 516 return c == ' ' || c == '\t' || c == '\f' || c == '\r' 517 || c == '\n'; 518 } 519 520 private static boolean isDigit(int c) { 521 return '0' <= c && c <= '9'; 522 } 523 524 private void ungetc(int c) { 525 lastChar = c; 526 } 527 528 private int getc() { 529 if (lastChar < 0) 530 if (position < maxlen) 531 return input.charAt(position++); 532 else 533 return -1; 534 else { 535 int c = lastChar; 536 lastChar = -1; 537 return c; 538 } 539 } 540 } 541 | Popular Tags |