1 15 16 package javassist.compiler; 17 18 import javassist.compiler.ast.*; 19 20 public final class Parser implements TokenId { 21 private Lex lex; 22 23 public Parser(Lex lex) { 24 this.lex = lex; 25 } 26 27 public boolean hasMore() { return lex.lookAhead() >= 0; } 28 29 32 public ASTList parseMember(SymbolTable tbl) throws CompileError { 33 ASTList mem = parseMember1(tbl); 34 if (mem instanceof MethodDecl) 35 return parseMethod2(tbl, (MethodDecl)mem); 36 else 37 return mem; 38 } 39 40 42 public ASTList parseMember1(SymbolTable tbl) throws CompileError { 43 ASTList mods = parseMemberMods(); 44 Declarator d; 45 boolean isConstructor = false; 46 if (lex.lookAhead() == Identifier && lex.lookAhead(1) == '(') { 47 d = new Declarator(VOID, 0); 48 isConstructor = true; 49 } 50 else 51 d = parseFormalType(tbl); 52 53 if (lex.get() != Identifier) 54 throw new SyntaxError(lex); 55 56 String name; 57 if (isConstructor) 58 name = MethodDecl.initName; 59 else 60 name = lex.getString(); 61 62 d.setVariable(new Symbol(name)); 63 if (isConstructor || lex.lookAhead() == '(') 64 return parseMethod1(tbl, isConstructor, mods, d); 65 else 66 return parseField(tbl, mods, d); 67 } 68 69 74 private FieldDecl parseField(SymbolTable tbl, ASTList mods, 75 Declarator d) throws CompileError 76 { 77 ASTree expr = null; 78 if (lex.lookAhead() == '=') { 79 lex.get(); 80 expr = parseExpression(tbl); 81 } 82 83 int c = lex.get(); 84 if (c == ';') 85 return new FieldDecl(mods, new ASTList(d, new ASTList(expr))); 86 else if (c == ',') 87 throw new CompileError( 88 "only one field can be declared in one declaration", lex); 89 else 90 throw new SyntaxError(lex); 91 } 92 93 103 private MethodDecl parseMethod1(SymbolTable tbl, boolean isConstructor, 104 ASTList mods, Declarator d) 105 throws CompileError 106 { 107 if (lex.get() != '(') 108 throw new SyntaxError(lex); 109 110 ASTList parms = null; 111 if (lex.lookAhead() != ')') 112 while (true) { 113 parms = ASTList.append(parms, parseFormalParam(tbl)); 114 int t = lex.lookAhead(); 115 if (t == ',') 116 lex.get(); 117 else if (t == ')') 118 break; 119 } 120 121 lex.get(); d.addArrayDim(parseArrayDimension()); 123 if (isConstructor && d.getArrayDim() > 0) 124 throw new SyntaxError(lex); 125 126 ASTList throwsList = null; 127 if (lex.lookAhead() == THROWS) { 128 lex.get(); 129 while (true) { 130 throwsList = ASTList.append(throwsList, parseClassType(tbl)); 131 if (lex.lookAhead() == ',') 132 lex.get(); 133 else 134 break; 135 } 136 } 137 138 return new MethodDecl(mods, new ASTList(d, 139 ASTList.make(parms, throwsList, null))); 140 } 141 142 144 public MethodDecl parseMethod2(SymbolTable tbl, MethodDecl md) 145 throws CompileError 146 { 147 Stmnt body = null; 148 if (lex.lookAhead() == ';') 149 lex.get(); 150 else { 151 body = parseBlock(tbl); 152 if (body == null) 153 body = new Stmnt(BLOCK); 154 } 155 156 md.sublist(4).setHead(body); 157 return md; 158 } 159 160 165 private ASTList parseMemberMods() { 166 int t; 167 ASTList list = null; 168 while (true) { 169 t = lex.lookAhead(); 170 if (t == ABSTRACT || t == FINAL || t == PUBLIC || t == PROTECTED 171 || t == PRIVATE || t == SYNCHRONIZED || t == STATIC 172 || t == VOLATILE || t == TRANSIENT || t == STRICT) 173 list = new ASTList(new Keyword(lex.get()), list); 174 else 175 break; 176 } 177 178 return list; 179 } 180 181 183 private Declarator parseFormalType(SymbolTable tbl) throws CompileError { 184 int t = lex.lookAhead(); 185 if (isBuiltinType(t) || t == VOID) { 186 lex.get(); int dim = parseArrayDimension(); 188 return new Declarator(t, dim); 189 } 190 else { 191 ASTList name = parseClassType(tbl); 192 int dim = parseArrayDimension(); 193 return new Declarator(name, dim); 194 } 195 } 196 197 private static boolean isBuiltinType(int t) { 198 return (t == BOOLEAN || t == BYTE || t == CHAR || t == SHORT 199 || t == INT || t == LONG || t == FLOAT || t == DOUBLE); 200 } 201 202 204 private Declarator parseFormalParam(SymbolTable tbl) 205 throws CompileError 206 { 207 Declarator d = parseFormalType(tbl); 208 if (lex.get() != Identifier) 209 throw new SyntaxError(lex); 210 211 String name = lex.getString(); 212 d.setVariable(new Symbol(name)); 213 d.addArrayDim(parseArrayDimension()); 214 tbl.append(name, d); 215 return d; 216 } 217 218 237 public Stmnt parseStatement(SymbolTable tbl) 238 throws CompileError 239 { 240 int t = lex.lookAhead(); 241 if (t == '{') 242 return parseBlock(tbl); 243 else if (t == ';') { 244 lex.get(); 245 return new Stmnt(BLOCK); } 247 else if (t == Identifier && lex.lookAhead(1) == ':') { 248 lex.get(); String label = lex.getString(); 250 lex.get(); return Stmnt.make(LABEL, new Symbol(label), parseStatement(tbl)); 252 } 253 else if (t == IF) 254 return parseIf(tbl); 255 else if (t == WHILE) 256 return parseWhile(tbl); 257 else if (t == DO) 258 return parseDo(tbl); 259 else if (t == FOR) 260 return parseFor(tbl); 261 else if (t == TRY) 262 return parseTry(tbl); 263 else if (t == SWITCH) 264 return parseSwitch(tbl); 265 else if (t == SYNCHRONIZED) 266 return parseSynchronized(tbl); 267 else if (t == RETURN) 268 return parseReturn(tbl); 269 else if (t == THROW) 270 return parseThrow(tbl); 271 else if (t == BREAK) 272 return parseBreak(tbl); 273 else if (t == CONTINUE) 274 return parseContinue(tbl); 275 else 276 return parseDeclarationOrExpression(tbl, false); 277 } 278 279 281 private Stmnt parseBlock(SymbolTable tbl) throws CompileError { 282 if (lex.get() != '{') 283 throw new SyntaxError(lex); 284 285 Stmnt body = null; 286 SymbolTable tbl2 = new SymbolTable(tbl); 287 while (lex.lookAhead() != '}') { 288 Stmnt s = parseStatement(tbl2); 289 if (s != null) 290 body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s)); 291 } 292 293 lex.get(); if (body == null) 295 return new Stmnt(BLOCK); else 297 return body; 298 } 299 300 303 private Stmnt parseIf(SymbolTable tbl) throws CompileError { 304 int t = lex.get(); ASTree expr = parseParExpression(tbl); 306 Stmnt thenp = parseStatement(tbl); 307 Stmnt elsep; 308 if (lex.lookAhead() == ELSE) { 309 lex.get(); 310 elsep = parseStatement(tbl); 311 } 312 else 313 elsep = null; 314 315 return new Stmnt(t, expr, new ASTList(thenp, new ASTList(elsep))); 316 } 317 318 320 private Stmnt parseWhile(SymbolTable tbl) 321 throws CompileError 322 { 323 int t = lex.get(); ASTree expr = parseParExpression(tbl); 325 Stmnt body = parseStatement(tbl); 326 return new Stmnt(t, expr, body); 327 } 328 329 331 private Stmnt parseDo(SymbolTable tbl) throws CompileError { 332 int t = lex.get(); Stmnt body = parseStatement(tbl); 334 if (lex.get() != WHILE || lex.get() != '(') 335 throw new SyntaxError(lex); 336 337 ASTree expr = parseExpression(tbl); 338 if (lex.get() != ')' || lex.get() != ';') 339 throw new SyntaxError(lex); 340 341 return new Stmnt(t, expr, body); 342 } 343 344 347 private Stmnt parseFor(SymbolTable tbl) throws CompileError { 348 Stmnt expr1, expr3; 349 ASTree expr2; 350 int t = lex.get(); 352 SymbolTable tbl2 = new SymbolTable(tbl); 353 354 if (lex.get() != '(') 355 throw new SyntaxError(lex); 356 357 if (lex.lookAhead() == ';') { 358 lex.get(); 359 expr1 = null; 360 } 361 else 362 expr1 = parseDeclarationOrExpression(tbl2, true); 363 364 if (lex.lookAhead() == ';') 365 expr2 = null; 366 else 367 expr2 = parseExpression(tbl2); 368 369 if (lex.get() != ';') 370 throw new CompileError("; is missing", lex); 371 372 if (lex.lookAhead() == ')') 373 expr3 = null; 374 else 375 expr3 = parseExprList(tbl2); 376 377 if (lex.get() != ')') 378 throw new CompileError(") is missing", lex); 379 380 Stmnt body = parseStatement(tbl2); 381 return new Stmnt(t, expr1, new ASTList(expr2, 382 new ASTList(expr3, body))); 383 } 384 385 392 private Stmnt parseSwitch(SymbolTable tbl) throws CompileError { 393 int t = lex.get(); ASTree expr = parseParExpression(tbl); 395 Stmnt body = parseSwitchBlock(tbl); 396 return new Stmnt(t, expr, body); 397 } 398 399 private Stmnt parseSwitchBlock(SymbolTable tbl) throws CompileError { 400 if (lex.get() != '{') 401 throw new SyntaxError(lex); 402 403 SymbolTable tbl2 = new SymbolTable(tbl); 404 Stmnt s = parseStmntOrCase(tbl2); 405 if (s == null) 406 throw new CompileError("empty switch block", lex); 407 408 int op = s.getOperator(); 409 if (op != CASE && op != DEFAULT) 410 throw new CompileError("no case or default in a switch block", 411 lex); 412 413 Stmnt body = new Stmnt(BLOCK, s); 414 while (lex.lookAhead() != '}') { 415 Stmnt s2 = parseStmntOrCase(tbl2); 416 if (s2 != null) { 417 int op2 = s2.getOperator(); 418 if (op2 == CASE || op2 == DEFAULT) { 419 body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s2)); 420 s = s2; 421 } 422 else 423 s = (Stmnt)ASTList.concat(s, new Stmnt(BLOCK, s2)); 424 } 425 } 426 427 lex.get(); return body; 429 } 430 431 private Stmnt parseStmntOrCase(SymbolTable tbl) throws CompileError { 432 int t = lex.lookAhead(); 433 if (t != CASE && t != DEFAULT) 434 return parseStatement(tbl); 435 436 lex.get(); 437 Stmnt s; 438 if (t == CASE) 439 s = new Stmnt(t, parseExpression(tbl)); 440 else 441 s = new Stmnt(DEFAULT); 442 443 if (lex.get() != ':') 444 throw new CompileError(": is missing", lex); 445 446 return s; 447 } 448 449 452 private Stmnt parseSynchronized(SymbolTable tbl) throws CompileError { 453 int t = lex.get(); if (lex.get() != '(') 455 throw new SyntaxError(lex); 456 457 ASTree expr = parseExpression(tbl); 458 if (lex.get() != ')') 459 throw new SyntaxError(lex); 460 461 Stmnt body = parseBlock(tbl); 462 return new Stmnt(t, expr, body); 463 } 464 465 470 private Stmnt parseTry(SymbolTable tbl) throws CompileError { 471 lex.get(); Stmnt block = parseBlock(tbl); 473 ASTList catchList = null; 474 while (lex.lookAhead() == CATCH) { 475 lex.get(); if (lex.get() != '(') 477 throw new SyntaxError(lex); 478 479 SymbolTable tbl2 = new SymbolTable(tbl); 480 Declarator d = parseFormalParam(tbl2); 481 if (d.getArrayDim() > 0 || d.getType() != CLASS) 482 throw new SyntaxError(lex); 483 484 if (lex.get() != ')') 485 throw new SyntaxError(lex); 486 487 Stmnt b = parseBlock(tbl2); 488 catchList = ASTList.append(catchList, new Pair(d, b)); 489 } 490 491 Stmnt finallyBlock = null; 492 if (lex.lookAhead() == FINALLY) { 493 lex.get(); finallyBlock = parseBlock(tbl); 495 } 496 497 return Stmnt.make(TRY, block, catchList, finallyBlock); 498 } 499 500 502 private Stmnt parseReturn(SymbolTable tbl) throws CompileError { 503 int t = lex.get(); Stmnt s = new Stmnt(t); 505 if (lex.lookAhead() != ';') 506 s.setLeft(parseExpression(tbl)); 507 508 if (lex.get() != ';') 509 throw new CompileError("; is missing", lex); 510 511 return s; 512 } 513 514 516 private Stmnt parseThrow(SymbolTable tbl) throws CompileError { 517 int t = lex.get(); ASTree expr = parseExpression(tbl); 519 if (lex.get() != ';') 520 throw new CompileError("; is missing", lex); 521 522 return new Stmnt(t, expr); 523 } 524 525 527 private Stmnt parseBreak(SymbolTable tbl) 528 throws CompileError 529 { 530 return parseContinue(tbl); 531 } 532 533 535 private Stmnt parseContinue(SymbolTable tbl) 536 throws CompileError 537 { 538 int t = lex.get(); Stmnt s = new Stmnt(t); 540 int t2 = lex.get(); 541 if (t2 == Identifier) { 542 s.setLeft(new Symbol(lex.getString())); 543 t2 = lex.get(); 544 } 545 546 if (t2 != ';') 547 throw new CompileError("; is missing", lex); 548 549 return s; 550 } 551 552 561 private Stmnt parseDeclarationOrExpression(SymbolTable tbl, 562 boolean exprList) 563 throws CompileError 564 { 565 int t = lex.lookAhead(); 566 while (t == FINAL) { 567 lex.get(); 568 t = lex.lookAhead(); 569 } 570 571 if (isBuiltinType(t)) { 572 t = lex.get(); 573 int dim = parseArrayDimension(); 574 return parseDeclarators(tbl, new Declarator(t, dim)); 575 } 576 else if (t == Identifier) { 577 int i = nextIsClassType(0); 578 if (i >= 0) 579 if (lex.lookAhead(i) == Identifier) { 580 ASTList name = parseClassType(tbl); 581 int dim = parseArrayDimension(); 582 return parseDeclarators(tbl, new Declarator(name, dim)); 583 } 584 } 585 586 Stmnt expr; 587 if (exprList) 588 expr = parseExprList(tbl); 589 else 590 expr = new Stmnt(EXPR, parseExpression(tbl)); 591 592 if (lex.get() != ';') 593 throw new CompileError("; is missing", lex); 594 595 return expr; 596 } 597 598 600 private Stmnt parseExprList(SymbolTable tbl) throws CompileError { 601 Stmnt expr = null; 602 for (;;) { 603 Stmnt e = new Stmnt(EXPR, parseExpression(tbl)); 604 expr = (Stmnt)ASTList.concat(expr, new Stmnt(BLOCK, e)); 605 if (lex.lookAhead() == ',') 606 lex.get(); 607 else 608 return expr; 609 } 610 } 611 612 614 private Stmnt parseDeclarators(SymbolTable tbl, Declarator d) 615 throws CompileError 616 { 617 Stmnt decl = null; 618 for (;;) { 619 decl = (Stmnt)ASTList.concat(decl, 620 new Stmnt(DECL, parseDeclarator(tbl, d))); 621 int t = lex.get(); 622 if (t == ';') 623 return decl; 624 else if (t != ',') 625 throw new CompileError("; is missing", lex); 626 } 627 } 628 629 631 private Declarator parseDeclarator(SymbolTable tbl, Declarator d) 632 throws CompileError 633 { 634 if (lex.get() != Identifier || d.getType() == VOID) 635 throw new SyntaxError(lex); 636 637 String name = lex.getString(); 638 Symbol symbol = new Symbol(name); 639 int dim = parseArrayDimension(); 640 ASTree init = null; 641 if (lex.lookAhead() == '=') { 642 lex.get(); 643 init = parseInitializer(tbl); 644 } 645 646 Declarator decl = d.make(symbol, dim, init); 647 tbl.append(name, decl); 648 return decl; 649 } 650 651 653 private ASTree parseInitializer(SymbolTable tbl) throws CompileError { 654 if (lex.lookAhead() == '{') 655 return parseArrayInitializer(tbl); 656 else 657 return parseExpression(tbl); 658 } 659 660 663 private ASTree parseArrayInitializer(SymbolTable tbl) 664 throws CompileError 665 { 666 lex.get(); throw new CompileError("array initializer is not supported", lex); 668 } 669 670 672 private ASTree parseParExpression(SymbolTable tbl) throws CompileError { 673 if (lex.get() != '(') 674 throw new SyntaxError(lex); 675 676 ASTree expr = parseExpression(tbl); 677 if (lex.get() != ')') 678 throw new SyntaxError(lex); 679 680 return expr; 681 } 682 683 686 public ASTree parseExpression(SymbolTable tbl) throws CompileError { 687 ASTree left = parseConditionalExpr(tbl); 688 if (!isAssignOp(lex.lookAhead())) 689 return left; 690 691 int t = lex.get(); 692 ASTree right = parseExpression(tbl); 693 return AssignExpr.makeAssign(t, left, right); 694 } 695 696 private static boolean isAssignOp(int t) { 697 return t == '=' || t == MOD_E || t == AND_E 698 || t == MUL_E || t == PLUS_E || t == MINUS_E || t == DIV_E 699 || t == EXOR_E || t == OR_E || t == LSHIFT_E 700 || t == RSHIFT_E || t == ARSHIFT_E; 701 } 702 703 706 private ASTree parseConditionalExpr(SymbolTable tbl) throws CompileError { 707 ASTree cond = parseBinaryExpr(tbl); 708 if (lex.lookAhead() == '?') { 709 lex.get(); 710 ASTree thenExpr = parseExpression(tbl); 711 if (lex.get() != ':') 712 throw new CompileError(": is missing", lex); 713 714 ASTree elseExpr = parseExpression(tbl); 715 return new CondExpr(cond, thenExpr, elseExpr); 716 } 717 else 718 return cond; 719 } 720 721 762 private ASTree parseBinaryExpr(SymbolTable tbl) throws CompileError { 763 ASTree expr = parseUnaryExpr(tbl); 764 for (;;) { 765 int t = lex.lookAhead(); 766 int p = getOpPrecedence(t); 767 if (p == 0) 768 return expr; 769 else 770 expr = binaryExpr2(tbl, expr, p); 771 } 772 } 773 774 private ASTree parseInstanceOf(SymbolTable tbl, ASTree expr) 775 throws CompileError 776 { 777 int t = lex.lookAhead(); 778 if (isBuiltinType(t)) { 779 lex.get(); int dim = parseArrayDimension(); 781 return new InstanceOfExpr(t, dim, expr); 782 } 783 else { 784 ASTList name = parseClassType(tbl); 785 int dim = parseArrayDimension(); 786 return new InstanceOfExpr(name, dim, expr); 787 } 788 } 789 790 private ASTree binaryExpr2(SymbolTable tbl, ASTree expr, int prec) 791 throws CompileError 792 { 793 int t = lex.get(); 794 if (t == INSTANCEOF) 795 return parseInstanceOf(tbl, expr); 796 797 ASTree expr2 = parseUnaryExpr(tbl); 798 for (;;) { 799 int t2 = lex.lookAhead(); 800 int p2 = getOpPrecedence(t2); 801 if (p2 != 0 && prec > p2) 802 expr2 = binaryExpr2(tbl, expr2, p2); 803 else 804 return BinExpr.makeBin(t, expr, expr2); 805 } 806 } 807 808 private static final int[] binaryOpPrecedence 810 = { 0, 0, 0, 0, 1, 6, 0, 0, 811 0, 1, 2, 0, 2, 0, 1, 0, 812 0, 0, 0, 0, 0, 0, 0, 0, 813 0, 0, 0, 4, 0, 4, 0 }; 814 815 private int getOpPrecedence(int c) { 816 if ('!' <= c && c <= '?') 817 return binaryOpPrecedence[c - '!']; 818 else if (c == '^') 819 return 7; 820 else if (c == '|') 821 return 8; 822 else if (c == ANDAND) 823 return 9; 824 else if (c == OROR) 825 return 10; 826 else if (c == EQ || c == NEQ) 827 return 5; 828 else if (c == LE || c == GE || c == INSTANCEOF) 829 return 4; 830 else if (c == LSHIFT || c == RSHIFT || c == ARSHIFT) 831 return 3; 832 else 833 return 0; } 835 836 845 private ASTree parseUnaryExpr(SymbolTable tbl) throws CompileError { 846 int t; 847 switch (lex.lookAhead()) { 848 case '+' : 849 case '-' : 850 case PLUSPLUS : 851 case MINUSMINUS : 852 case '!' : 853 case '~' : 854 t = lex.get(); 855 return Expr.make(t, parseUnaryExpr(tbl)); 856 case '(' : 857 return parseCast(tbl); 858 default : 859 return parsePostfix(tbl); 860 } 861 } 862 863 871 private ASTree parseCast(SymbolTable tbl) throws CompileError { 872 int t = lex.lookAhead(1); 873 if (isBuiltinType(t) && nextIsBuiltinCast()) { 874 lex.get(); lex.get(); int dim = parseArrayDimension(); 877 if (lex.get() != ')') 878 throw new CompileError(") is missing", lex); 879 880 return new CastExpr(t, dim, parseUnaryExpr(tbl)); 881 } 882 else if (t == Identifier && nextIsClassCast()) { 883 lex.get(); ASTList name = parseClassType(tbl); 885 int dim = parseArrayDimension(); 886 if (lex.get() != ')') 887 throw new CompileError(") is missing", lex); 888 889 return new CastExpr(name, dim, parseUnaryExpr(tbl)); 890 } 891 else 892 return parsePostfix(tbl); 893 } 894 895 private boolean nextIsBuiltinCast() { 896 int t; 897 int i = 2; 898 while ((t = lex.lookAhead(i++)) == '[') 899 if (lex.lookAhead(i++) != ']') 900 return false; 901 902 return lex.lookAhead(i - 1) == ')'; 903 } 904 905 private boolean nextIsClassCast() { 906 int i = nextIsClassType(1); 907 if (i < 0) 908 return false; 909 910 int t = lex.lookAhead(i); 911 if (t != ')') 912 return false; 913 914 t = lex.lookAhead(i + 1); 915 return t == '(' || t == NULL || t == StringL 916 || t == Identifier || t == THIS || t == SUPER || t == NEW 917 || t == TRUE || t == FALSE || t == LongConstant 918 || t == IntConstant || t == CharConstant 919 || t == DoubleConstant || t == FloatConstant; 920 } 921 922 private int nextIsClassType(int i) { 923 int t; 924 while (lex.lookAhead(++i) == '.') 925 if (lex.lookAhead(++i) != Identifier) 926 return -1; 927 928 while ((t = lex.lookAhead(i++)) == '[') 929 if (lex.lookAhead(i++) != ']') 930 return -1; 931 932 return i - 1; 933 } 934 935 937 private int parseArrayDimension() throws CompileError { 938 int arrayDim = 0; 939 while (lex.lookAhead() == '[') { 940 ++arrayDim; 941 lex.get(); 942 if (lex.get() != ']') 943 throw new CompileError("] is missing", lex); 944 } 945 946 return arrayDim; 947 } 948 949 951 private ASTList parseClassType(SymbolTable tbl) throws CompileError { 952 ASTList list = null; 953 for (;;) { 954 if (lex.get() != Identifier) 955 throw new SyntaxError(lex); 956 957 list = ASTList.append(list, new Symbol(lex.getString())); 958 if (lex.lookAhead() == '.') 959 lex.get(); 960 else 961 break; 962 } 963 964 return list; 965 } 966 967 983 private ASTree parsePostfix(SymbolTable tbl) throws CompileError { 984 int token = lex.lookAhead(); 985 switch (token) { 986 case LongConstant : 987 case IntConstant : 988 case CharConstant : 989 lex.get(); 990 return new IntConst(lex.getLong(), token); 991 case DoubleConstant : 992 case FloatConstant : 993 lex.get(); 994 return new DoubleConst(lex.getDouble(), token); 995 default : 996 break; 997 } 998 999 String str; 1000 ASTree index; 1001 ASTree expr = parsePrimaryExpr(tbl); 1002 int t; 1003 while (true) { 1004 switch (lex.lookAhead()) { 1005 case '(' : 1006 expr = parseMethodCall(tbl, expr); 1007 break; 1008 case '[' : 1009 if (lex.lookAhead(1) == ']') { 1010 int dim = parseArrayDimension(); 1011 if (lex.get() != '.' || lex.get() != CLASS) 1012 throw new SyntaxError(lex); 1013 1014 expr = parseDotClass(expr, dim); 1015 } 1016 else { 1017 index = parseArrayIndex(tbl); 1018 if (index == null) 1019 throw new SyntaxError(lex); 1020 1021 expr = Expr.make(ARRAY, expr, index); 1022 } 1023 break; 1024 case PLUSPLUS : 1025 case MINUSMINUS : 1026 t = lex.get(); 1027 expr = Expr.make(t, null, expr); 1028 break; 1029 case '.' : 1030 lex.get(); 1031 t = lex.get(); 1032 if (t == CLASS) { 1033 expr = parseDotClass(expr, 0); 1034 } 1035 else if (t == Identifier) { 1036 str = lex.getString(); 1037 expr = Expr.make('.', expr, new Member(str)); 1038 } 1039 else 1040 throw new CompileError("missing member name", lex); 1041 break; 1042 case '#' : 1043 lex.get(); 1044 t = lex.get(); 1045 if (t != Identifier) 1046 throw new CompileError("missing static member name", lex); 1047 1048 str = lex.getString(); 1049 expr = Expr.make(MEMBER, new Symbol(toClassName(expr)), 1050 new Member(str)); 1051 break; 1052 default : 1053 return expr; 1054 } 1055 } 1056 } 1057 1058 1062 private ASTree parseDotClass(ASTree className, int dim) 1063 throws CompileError 1064 { 1065 String cname = toClassName(className); 1066 if (dim > 0) { 1067 StringBuffer sbuf = new StringBuffer (); 1068 while (dim-- > 0) 1069 sbuf.append('['); 1070 1071 sbuf.append('L').append(cname.replace('.', '/')).append(';'); 1072 cname = sbuf.toString(); 1073 } 1074 1075 return Expr.make('.', new Symbol(cname), new Member("class")); 1076 } 1077 1078 1082 private ASTree parseDotClass(int builtinType, int dim) 1083 throws CompileError 1084 { 1085 if (dim > 0) { 1086 String cname = CodeGen.toJvmTypeName(builtinType, dim); 1087 return Expr.make('.', new Symbol(cname), new Member("class")); 1088 } 1089 else { 1090 String cname; 1091 switch(builtinType) { 1092 case BOOLEAN : 1093 cname = "java.lang.Boolean"; 1094 break; 1095 case BYTE : 1096 cname = "java.lang.Byte"; 1097 break; 1098 case CHAR : 1099 cname = "java.lang.Character"; 1100 break; 1101 case SHORT : 1102 cname = "java.lang.Short"; 1103 break; 1104 case INT : 1105 cname = "java.lang.Integer"; 1106 break; 1107 case LONG : 1108 cname = "java.lang.Long"; 1109 break; 1110 case FLOAT : 1111 cname = "java.lang.Float"; 1112 break; 1113 case DOUBLE : 1114 cname = "java.lang.Double"; 1115 break; 1116 case VOID : 1117 cname = "java.lang.Void"; 1118 break; 1119 default : 1120 throw new CompileError("invalid builtin type: " 1121 + builtinType); 1122 } 1123 1124 return Expr.make(MEMBER, new Symbol(cname), new Member("TYPE")); 1125 } 1126 } 1127 1128 1133 private ASTree parseMethodCall(SymbolTable tbl, ASTree expr) 1134 throws CompileError 1135 { 1136 if (expr instanceof Keyword) { 1137 int token = ((Keyword)expr).get(); 1138 if (token != THIS && token != SUPER) 1139 throw new SyntaxError(lex); 1140 } 1141 else if (expr instanceof Symbol) ; 1143 else if (expr instanceof Expr) { 1144 int op = ((Expr)expr).getOperator(); 1145 if (op != '.' && op != MEMBER) 1146 throw new SyntaxError(lex); 1147 } 1148 1149 return CallExpr.makeCall(expr, parseArgumentList(tbl)); 1150 } 1151 1152 private String toClassName(ASTree name) 1153 throws CompileError 1154 { 1155 StringBuffer sbuf = new StringBuffer (); 1156 toClassName(name, sbuf); 1157 return sbuf.toString(); 1158 } 1159 1160 private void toClassName(ASTree name, StringBuffer sbuf) 1161 throws CompileError 1162 { 1163 if (name instanceof Symbol) { 1164 sbuf.append(((Symbol)name).get()); 1165 return; 1166 } 1167 else if (name instanceof Expr) { 1168 Expr expr = (Expr)name; 1169 if (expr.getOperator() == '.') { 1170 toClassName(expr.oprand1(), sbuf); 1171 sbuf.append('.'); 1172 toClassName(expr.oprand2(), sbuf); 1173 return; 1174 } 1175 } 1176 1177 throw new CompileError("bad static member access", lex); 1178 } 1179 1180 1190 private ASTree parsePrimaryExpr(SymbolTable tbl) throws CompileError { 1191 int t; 1192 String name; 1193 Declarator decl; 1194 ASTree expr; 1195 1196 switch (t = lex.get()) { 1197 case THIS : 1198 case SUPER : 1199 case TRUE : 1200 case FALSE : 1201 case NULL : 1202 return new Keyword(t); 1203 case Identifier : 1204 name = lex.getString(); 1205 decl = tbl.lookup(name); 1206 if (decl == null) 1207 return new Member(name); else 1209 return new Variable(name, decl); case StringL : 1211 return new StringL(lex.getString()); 1212 case NEW : 1213 return parseNew(tbl); 1214 case '(' : 1215 expr = parseExpression(tbl); 1216 if (lex.get() == ')') 1217 return expr; 1218 else 1219 throw new CompileError(") is missing", lex); 1220 default : 1221 if (isBuiltinType(t) || t == VOID) { 1222 int dim = parseArrayDimension(); 1223 if (lex.get() == '.' && lex.get() == CLASS) 1224 return parseDotClass(t, dim); 1225 } 1226 1227 throw new SyntaxError(lex); 1228 } 1229 } 1230 1231 1235 private NewExpr parseNew(SymbolTable tbl) throws CompileError { 1236 ASTree init = null; 1237 int t = lex.lookAhead(); 1238 if (isBuiltinType(t)) { 1239 lex.get(); 1240 ASTList size = parseArraySize(tbl); 1241 if (lex.lookAhead() == '{') 1242 init = parseArrayInitializer(tbl); 1243 1244 return new NewExpr(t, size, init); 1245 } 1246 else if (t == Identifier) { 1247 ASTList name = parseClassType(tbl); 1248 t = lex.lookAhead(); 1249 if (t == '(') { 1250 ASTList args = parseArgumentList(tbl); 1251 return new NewExpr(name, args); 1252 } 1253 else if (t == '[') { 1254 ASTList size = parseArraySize(tbl); 1255 if (lex.lookAhead() == '{') 1256 init = parseArrayInitializer(tbl); 1257 1258 return NewExpr.makeObjectArray(name, size, init); 1259 } 1260 } 1261 1262 throw new SyntaxError(lex); 1263 } 1264 1265 1267 private ASTList parseArraySize(SymbolTable tbl) throws CompileError { 1268 ASTList list = null; 1269 while (lex.lookAhead() == '[') 1270 list = ASTList.append(list, parseArrayIndex(tbl)); 1271 1272 return list; 1273 } 1274 1275 1277 private ASTree parseArrayIndex(SymbolTable tbl) throws CompileError { 1278 lex.get(); if (lex.lookAhead() == ']') { 1280 lex.get(); 1281 return null; 1282 } 1283 else { 1284 ASTree index = parseExpression(tbl); 1285 if (lex.get() != ']') 1286 throw new CompileError("] is missing", lex); 1287 1288 return index; 1289 } 1290 } 1291 1292 1294 private ASTList parseArgumentList(SymbolTable tbl) throws CompileError { 1295 if (lex.get() != '(') 1296 throw new CompileError("( is missing", lex); 1297 1298 ASTList list = null; 1299 if (lex.lookAhead() != ')') 1300 for (;;) { 1301 list = ASTList.append(list, parseExpression(tbl)); 1302 if (lex.lookAhead() == ',') 1303 lex.get(); 1304 else 1305 break; 1306 } 1307 1308 if (lex.get() != ')') 1309 throw new CompileError(") is missing", lex); 1310 1311 return list; 1312 } 1313} 1314 1315 | Popular Tags |