1/* 2 * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package sun.tools.java; 27 28import sun.tools.tree.*; 29import java.io.IOException; 30import java.io.InputStream; 31import java.util.Enumeration; 32import java.util.Vector; 33 34/** 35 * This class is used to parse Java statements and expressions. 36 * The result is a parse tree.<p> 37 * 38 * This class implements an operator precedence parser. Errors are 39 * reported to the Environment object, if the error can't be 40 * resolved immediately, a SyntaxError exception is thrown.<p> 41 * 42 * Error recovery is implemented by catching SyntaxError exceptions 43 * and discarding input tokens until an input token is reached that 44 * is possibly a legal continuation.<p> 45 * 46 * The parse tree that is constructed represents the input 47 * exactly (no rewrites to simpler forms). This is important 48 * if the resulting tree is to be used for code formatting in 49 * a programming environment. Currently only documentation comments 50 * are retained.<p> 51 * 52 * The parsing algorithm does NOT use any type information. Changes 53 * in the type system do not affect the structure of the parse tree. 54 * This restriction does introduce an ambiguity an expression of the 55 * form: (e1) e2 is assumed to be a cast if e2 does not start with 56 * an operator. That means that (a) - b is interpreted as subtract 57 * b from a and not cast negative b to type a. However, if a is a 58 * simple type (byte, int, ...) then it is assumed to be a cast.<p> 59 * 60 * WARNING: The contents of this source file are not part of any 61 * supported API. Code that depends on them does so at its own risk: 62 * they are subject to change or removal without notice. 63 * 64 * @author Arthur van Hoff 65 */ 66 67public 68class Parser extends Scanner implements ParserActions, Constants { 69 /** 70 * Create a parser 71 */ 72 protected Parser(Environment env, InputStream in) throws IOException { 73 super(env, in); 74 this.scanner = this; 75 this.actions = this; 76 } 77 78 /** 79 * Create a parser, given a scanner. 80 */ 81 protected Parser(Scanner scanner) throws IOException { 82 super(scanner.env); 83 this.scanner = scanner; 84 ((Scanner)this).env = scanner.env; 85 ((Scanner)this).token = scanner.token; 86 ((Scanner)this).pos = scanner.pos; 87 this.actions = this; 88 } 89 90 /** 91 * Create a parser, given a scanner and the semantic callback. 92 */ 93 public Parser(Scanner scanner, ParserActions actions) throws IOException { 94 this(scanner); 95 this.actions = actions; 96 } 97 98 /** 99 * Usually <code>this.actions == (ParserActions)this</code>. 100 * However, a delegate scanner can produce tokens for this parser, 101 * in which case <code>(Scanner)this</code> is unused, 102 * except for <code>this.token</code> and <code>this.pos</code> 103 * instance variables which are filled from the real scanner 104 * by <code>this.scan()</code> and the constructor. 105 */ 106 ParserActions actions; 107 108 // Note: The duplication of methods allows pre-1.1 classes to 109 // be binary compatible with the new version of the parser, 110 // which now passes IdentifierTokens to the semantics phase, 111 // rather than just Identifiers. This change is necessary, 112 // since the parser is no longer responsible for managing the 113 // resolution of type names. (That caused the "Vector" bug.) 114 // 115 // In a future release, the old "plain-Identifier" methods will 116 // go away, and the corresponding "IdentifierToken" methods 117 // may become abstract. 118 119 /** 120 * package declaration 121 * @deprecated 122 */ 123 @Deprecated 124 public void packageDeclaration(long off, IdentifierToken nm) { 125 // By default, call the deprecated version. 126 // Any application must override one of the packageDeclaration methods. 127 packageDeclaration(off, nm.id); 128 } 129 /** 130 * @deprecated 131 */ 132 @Deprecated 133 protected void packageDeclaration(long off, Identifier nm) { 134 throw new RuntimeException("beginClass method is abstract"); 135 } 136 137 /** 138 * import class 139 * @deprecated 140 */ 141 @Deprecated 142 public void importClass(long off, IdentifierToken nm) { 143 // By default, call the deprecated version. 144 // Any application must override one of the packageDeclaration methods. 145 importClass(off, nm.id); 146 } 147 /** 148 * @deprecated Use the version with the IdentifierToken arguments. 149 */ 150 @Deprecated 151 protected void importClass(long off, Identifier nm) { 152 throw new RuntimeException("importClass method is abstract"); 153 } 154 155 /** 156 * import package 157 * @deprecated 158 */ 159 @Deprecated 160 public void importPackage(long off, IdentifierToken nm) { 161 // By default, call the deprecated version. 162 // Any application must override one of the importPackage methods. 163 importPackage(off, nm.id); 164 } 165 /** 166 * @deprecated Use the version with the IdentifierToken arguments. 167 */ 168 @Deprecated 169 protected void importPackage(long off, Identifier nm) { 170 throw new RuntimeException("importPackage method is abstract"); 171 } 172 173 /** 174 * Define class 175 * @deprecated 176 */ 177 @Deprecated 178 public ClassDefinition beginClass(long off, String doc, 179 int mod, IdentifierToken nm, 180 IdentifierToken sup, 181 IdentifierToken impl[]) { 182 // By default, call the deprecated version. 183 // Any application must override one of the beginClass methods. 184 Identifier supId = (sup == null) ? null : sup.id; 185 Identifier implIds[] = null; 186 if (impl != null) { 187 implIds = new Identifier[impl.length]; 188 for (int i = 0; i < impl.length; i++) { 189 implIds[i] = impl[i].id; 190 } 191 } 192 beginClass(off, doc, mod, nm.id, supId, implIds); 193 return getCurrentClass(); 194 } 195 /** 196 * @deprecated Use the version with the IdentifierToken arguments. 197 */ 198 @Deprecated 199 protected void beginClass(long off, String doc, int mod, Identifier nm, 200 Identifier sup, Identifier impl[]) { 201 throw new RuntimeException("beginClass method is abstract"); 202 } 203 204 /** 205 * Report the current class under construction. 206 * By default, it's a no-op which returns null. 207 * It may only be called before the corresponding endClass(). 208 */ 209 protected ClassDefinition getCurrentClass() { 210 return null; 211 } 212 213 /** 214 * End class 215 * @deprecated 216 */ 217 @Deprecated 218 public void endClass(long off, ClassDefinition c) { 219 // By default, call the deprecated version. 220 // Any application must override one of the beginClass methods. 221 endClass(off, c.getName().getFlatName().getName()); 222 } 223 /** 224 * @deprecated Use the version with the IdentifierToken arguments. 225 */ 226 @Deprecated 227 protected void endClass(long off, Identifier nm) { 228 throw new RuntimeException("endClass method is abstract"); 229 } 230 231 /** 232 * Define a field 233 * @deprecated 234 */ 235 @Deprecated 236 public void defineField(long where, ClassDefinition c, 237 String doc, int mod, Type t, 238 IdentifierToken nm, IdentifierToken args[], 239 IdentifierToken exp[], Node val) { 240 // By default, call the deprecated version. 241 // Any application must override one of the defineField methods. 242 Identifier argIds[] = null; 243 Identifier expIds[] = null; 244 if (args != null) { 245 argIds = new Identifier[args.length]; 246 for (int i = 0; i < args.length; i++) { 247 argIds[i] = args[i].id; 248 } 249 } 250 if (exp != null) { 251 expIds = new Identifier[exp.length]; 252 for (int i = 0; i < exp.length; i++) { 253 expIds[i] = exp[i].id; 254 } 255 } 256 defineField(where, doc, mod, t, nm.id, argIds, expIds, val); 257 } 258 259 /** 260 * @deprecated Use the version with the IdentifierToken arguments. 261 */ 262 @Deprecated 263 protected void defineField(long where, String doc, int mod, Type t, 264 Identifier nm, Identifier args[], 265 Identifier exp[], Node val) { 266 throw new RuntimeException("defineField method is abstract"); 267 } 268 269 /* 270 * A growable array of nodes. It is used as a growable 271 * buffer to hold argument lists and expression lists. 272 * I'm not using Vector to make it more efficient. 273 */ 274 private Node args[] = new Node[32]; 275 protected int argIndex = 0; 276 277 protected final void addArgument(Node n) { 278 if (argIndex == args.length) { 279 Node newArgs[] = new Node[args.length * 2]; 280 System.arraycopy(args, 0, newArgs, 0, args.length); 281 args = newArgs; 282 } 283 args[argIndex++] = n; 284 } 285 protected final Expression exprArgs(int index)[] { 286 Expression e[] = new Expression[argIndex - index]; 287 System.arraycopy(args, index, e, 0, argIndex - index); 288 argIndex = index; 289 return e; 290 } 291 protected final Statement statArgs(int index)[] { 292 Statement s[] = new Statement[argIndex - index]; 293 System.arraycopy(args, index, s, 0, argIndex - index); 294 argIndex = index; 295 return s; 296 } 297 298 /** 299 * Expect a token, return its value, scan the next token or 300 * throw an exception. 301 */ 302 protected void expect(int t) throws SyntaxError, IOException { 303 if (token != t) { 304 switch (t) { 305 case IDENT: 306 env.error(scanner.prevPos, "identifier.expected"); 307 break; 308 default: 309 env.error(scanner.prevPos, "token.expected", opNames[t]); 310 break; 311 } 312 throw new SyntaxError(); 313 } 314 scan(); 315 } 316 317 /** 318 * Parse a type expression. Does not parse the []'s. 319 */ 320 protected Expression parseTypeExpression() throws SyntaxError, IOException { 321 switch (token) { 322 case VOID: 323 return new TypeExpression(scan(), Type.tVoid); 324 case BOOLEAN: 325 return new TypeExpression(scan(), Type.tBoolean); 326 case BYTE: 327 return new TypeExpression(scan(), Type.tByte); 328 case CHAR: 329 return new TypeExpression(scan(), Type.tChar); 330 case SHORT: 331 return new TypeExpression(scan(), Type.tShort); 332 case INT: 333 return new TypeExpression(scan(), Type.tInt); 334 case LONG: 335 return new TypeExpression(scan(), Type.tLong); 336 case FLOAT: 337 return new TypeExpression(scan(), Type.tFloat); 338 case DOUBLE: 339 return new TypeExpression(scan(), Type.tDouble); 340 case IDENT: 341 Expression e = new IdentifierExpression(pos, scanner.idValue); 342 scan(); 343 while (token == FIELD) { 344 e = new FieldExpression(scan(), e, scanner.idValue); 345 expect(IDENT); 346 } 347 return e; 348 } 349 350 env.error(pos, "type.expected"); 351 throw new SyntaxError(); 352 } 353 354 /** 355 * Parse a method invocation. Should be called when the current 356 * then is the '(' of the argument list. 357 */ 358 protected Expression parseMethodExpression(Expression e, Identifier id) throws SyntaxError, IOException { 359 long p = scan(); 360 int i = argIndex; 361 if (token != RPAREN) { 362 addArgument(parseExpression()); 363 while (token == COMMA) { 364 scan(); 365 addArgument(parseExpression()); 366 } 367 } 368 expect(RPAREN); 369 return new MethodExpression(p, e, id, exprArgs(i)); 370 } 371 372 /** 373 * Parse a new instance expression. Should be called when the current 374 * token is the '(' of the argument list. 375 */ 376 protected Expression parseNewInstanceExpression(long p, Expression outerArg, Expression type) throws SyntaxError, IOException { 377 int i = argIndex; 378 expect(LPAREN); 379 if (token != RPAREN) { 380 addArgument(parseExpression()); 381 while (token == COMMA) { 382 scan(); 383 addArgument(parseExpression()); 384 } 385 } 386 expect(RPAREN); 387 ClassDefinition body = null; 388 if (token == LBRACE && !(type instanceof TypeExpression)) { 389 long tp = pos; 390 // x = new Type(arg) { subclass body ... } 391 Identifier superName = FieldExpression.toIdentifier(type); 392 if (superName == null) { 393 env.error(type.getWhere(), "type.expected"); 394 } 395 Vector<IdentifierToken> ext = new Vector<>(1); 396 Vector<IdentifierToken> impl = new Vector<>(0); 397 ext.addElement(new IdentifierToken(idNull)); 398 if (token == IMPLEMENTS || token == EXTENDS) { 399 env.error(pos, "anonymous.extends"); 400 parseInheritance(ext, impl); // error recovery 401 } 402 body = parseClassBody(new IdentifierToken(tp, idNull), 403 M_ANONYMOUS | M_LOCAL, EXPR, null, 404 ext, impl, type.getWhere()); 405 } 406 if (outerArg == null && body == null) { 407 return new NewInstanceExpression(p, type, exprArgs(i)); 408 } 409 return new NewInstanceExpression(p, type, exprArgs(i), outerArg, body); 410 } 411 412 /** 413 * Parse a primary expression. 414 */ 415 protected Expression parseTerm() throws SyntaxError, IOException { 416 switch (token) { 417 case CHARVAL: { 418 char v = scanner.charValue; 419 return new CharExpression(scan(), v); 420 } 421 case INTVAL: { 422 int v = scanner.intValue; 423 long q = scan(); 424 if (v < 0 && radix == 10) env.error(q, "overflow.int.dec"); 425 return new IntExpression(q, v); 426 } 427 case LONGVAL: { 428 long v = scanner.longValue; 429 long q = scan(); 430 if (v < 0 && radix == 10) env.error(q, "overflow.long.dec"); 431 return new LongExpression(q, v); 432 } 433 case FLOATVAL: { 434 float v = scanner.floatValue; 435 return new FloatExpression(scan(), v); 436 } 437 case DOUBLEVAL: { 438 double v = scanner.doubleValue; 439 return new DoubleExpression(scan(), v); 440 } 441 case STRINGVAL: { 442 String v = scanner.stringValue; 443 return new StringExpression(scan(), v); 444 } 445 case IDENT: { 446 Identifier v = scanner.idValue; 447 long p = scan(); 448 return (token == LPAREN) ? 449 parseMethodExpression(null, v) : new IdentifierExpression(p, v); 450 } 451 452 case TRUE: 453 return new BooleanExpression(scan(), true); 454 case FALSE: 455 return new BooleanExpression(scan(), false); 456 case NULL: 457 return new NullExpression(scan()); 458 459 case THIS: { 460 Expression e = new ThisExpression(scan()); 461 return (token == LPAREN) ? parseMethodExpression(e, idInit) : e; 462 } 463 case SUPER: { 464 Expression e = new SuperExpression(scan()); 465 return (token == LPAREN) ? parseMethodExpression(e, idInit) : e; 466 } 467 468 case VOID: 469 case BOOLEAN: 470 case BYTE: 471 case CHAR: 472 case SHORT: 473 case INT: 474 case LONG: 475 case FLOAT: 476 case DOUBLE: 477 return parseTypeExpression(); 478 479 case ADD: { 480 long p = scan(); 481 switch (token) { 482 case INTVAL: { 483 int v = scanner.intValue; 484 long q = scan(); 485 if (v < 0 && radix == 10) env.error(q, "overflow.int.dec"); 486 return new IntExpression(q, v); 487 } 488 case LONGVAL: { 489 long v = scanner.longValue; 490 long q = scan(); 491 if (v < 0 && radix == 10) env.error(q, "overflow.long.dec"); 492 return new LongExpression(q, v); 493 } 494 case FLOATVAL: { 495 float v = scanner.floatValue; 496 return new FloatExpression(scan(), v); 497 } 498 case DOUBLEVAL: { 499 double v = scanner.doubleValue; 500 return new DoubleExpression(scan(), v); 501 } 502 } 503 return new PositiveExpression(p, parseTerm()); 504 } 505 case SUB: { 506 long p = scan(); 507 switch (token) { 508 case INTVAL: { 509 int v = -scanner.intValue; 510 return new IntExpression(scan(), v); 511 } 512 case LONGVAL: { 513 long v = -scanner.longValue; 514 return new LongExpression(scan(), v); 515 } 516 case FLOATVAL: { 517 float v = -scanner.floatValue; 518 return new FloatExpression(scan(), v); 519 } 520 case DOUBLEVAL: { 521 double v = -scanner.doubleValue; 522 return new DoubleExpression(scan(), v); 523 } 524 } 525 return new NegativeExpression(p, parseTerm()); 526 } 527 case NOT: 528 return new NotExpression(scan(), parseTerm()); 529 case BITNOT: 530 return new BitNotExpression(scan(), parseTerm()); 531 case INC: 532 return new PreIncExpression(scan(), parseTerm()); 533 case DEC: 534 return new PreDecExpression(scan(), parseTerm()); 535 536 case LPAREN: { 537 // bracketed-expr: (expr) 538 long p = scan(); 539 Expression e = parseExpression(); 540 expect(RPAREN); 541 542 if (e.getOp() == TYPE) { 543 // cast-expr: (simple-type) expr 544 return new CastExpression(p, e, parseTerm()); 545 } 546 547 switch (token) { 548 549 // We handle INC and DEC specially. 550 // See the discussion in JLS section 15.14.1. 551 // (Part of fix for 4044502.) 552 553 case INC: 554 // We know this must be a postfix increment. 555 return new PostIncExpression(scan(), e); 556 557 case DEC: 558 // We know this must be a postfix decrement. 559 return new PostDecExpression(scan(), e); 560 561 case LPAREN: 562 case CHARVAL: 563 case INTVAL: 564 case LONGVAL: 565 case FLOATVAL: 566 case DOUBLEVAL: 567 case STRINGVAL: 568 case IDENT: 569 case TRUE: 570 case FALSE: 571 case NOT: 572 case BITNOT: 573 case THIS: 574 case SUPER: 575 case NULL: 576 case NEW: 577 // cast-expr: (expr) expr 578 return new CastExpression(p, e, parseTerm()); 579 } 580 return new ExprExpression(p, e); 581 } 582 583 case LBRACE: { 584 // array initializer: {expr1, expr2, ... exprn} 585 long p = scan(); 586 int i = argIndex; 587 if (token != RBRACE) { 588 addArgument(parseExpression()); 589 while (token == COMMA) { 590 scan(); 591 if (token == RBRACE) { 592 break; 593 } 594 addArgument(parseExpression()); 595 } 596 } 597 expect(RBRACE); 598 return new ArrayExpression(p, exprArgs(i)); 599 } 600 601 case NEW: { 602 long p = scan(); 603 int i = argIndex; 604 605 if (token == LPAREN) { 606 scan(); 607 Expression e = parseExpression(); 608 expect(RPAREN); 609 env.error(p, "not.supported", "new(...)"); 610 return new NullExpression(p); 611 } 612 613 Expression e = parseTypeExpression(); 614 615 if (token == LSQBRACKET) { 616 while (token == LSQBRACKET) { 617 scan(); 618 addArgument((token != RSQBRACKET) ? parseExpression() : null); 619 expect(RSQBRACKET); 620 } 621 Expression[] dims = exprArgs(i); 622 if (token == LBRACE) { 623 return new NewArrayExpression(p, e, dims, parseTerm()); 624 } 625 return new NewArrayExpression(p, e, dims); 626 } else { 627 return parseNewInstanceExpression(p, null, e); 628 } 629 } 630 } 631 632 // System.err.println("NEAR: " + opNames[token]); 633 env.error(scanner.prevPos, "missing.term"); 634 return new IntExpression(pos, 0); 635 } 636 637 /** 638 * Parse an expression. 639 */ 640 protected Expression parseExpression() throws SyntaxError, IOException { 641 for (Expression e = parseTerm() ; e != null ; e = e.order()) { 642 Expression more = parseBinaryExpression(e); 643 if (more == null) 644 return e; 645 e = more; 646 } 647 // this return is bogus 648 return null; 649 } 650 651 /** 652 * Given a left-hand term, parse an operator and right-hand term. 653 */ 654 protected Expression parseBinaryExpression(Expression e) throws SyntaxError, IOException { 655 if (e != null) { 656 switch (token) { 657 case LSQBRACKET: { 658 // index: expr1[expr2] 659 long p = scan(); 660 Expression index = (token != RSQBRACKET) ? parseExpression() : null; 661 expect(RSQBRACKET); 662 e = new ArrayAccessExpression(p, e, index); 663 break; 664 } 665 666 case INC: 667 e = new PostIncExpression(scan(), e); 668 break; 669 case DEC: 670 e = new PostDecExpression(scan(), e); 671 break; 672 case FIELD: { 673 long p = scan(); 674 if (token == THIS) { 675 // class C { class N { ... C.this ... } } 676 // class C { class N { N(C c){ ... c.this() ... } } } 677 long q = scan(); 678 if (token == LPAREN) { 679 e = new ThisExpression(q, e); 680 e = parseMethodExpression(e, idInit); 681 } else { 682 e = new FieldExpression(p, e, idThis); 683 } 684 break; 685 } 686 if (token == SUPER) { 687 // class D extends C.N { D(C.N n) { n.super(); } } 688 // Also, 'C.super', as in: 689 // class C extends CS { class N { ... C.super.foo ... } } 690 // class C extends CS { class N { ... C.super.foo() ... } } 691 long q = scan(); 692 if (token == LPAREN) { 693 e = new SuperExpression(q, e); 694 e = parseMethodExpression(e, idInit); 695 } else { 696 // We must check elsewhere that this expression 697 // does not stand alone, but qualifies a member name. 698 e = new FieldExpression(p, e, idSuper); 699 } 700 break; 701 } 702 if (token == NEW) { 703 // new C().new N() 704 scan(); 705 if (token != IDENT) 706 expect(IDENT); 707 e = parseNewInstanceExpression(p, e, parseTypeExpression()); 708 break; 709 } 710 if (token == CLASS) { 711 // just class literals, really 712 // Class c = C.class; 713 scan(); 714 e = new FieldExpression(p, e, idClass); 715 break; 716 } 717 Identifier id = scanner.idValue; 718 expect(IDENT); 719 if (token == LPAREN) { 720 e = parseMethodExpression(e, id); 721 } else { 722 e = new FieldExpression(p, e, id); 723 } 724 break; 725 } 726 case INSTANCEOF: 727 e = new InstanceOfExpression(scan(), e, parseTerm()); 728 break; 729 case ADD: 730 e = new AddExpression(scan(), e, parseTerm()); 731 break; 732 case SUB: 733 e = new SubtractExpression(scan(), e, parseTerm()); 734 break; 735 case MUL: 736 e = new MultiplyExpression(scan(), e, parseTerm()); 737 break; 738 case DIV: 739 e = new DivideExpression(scan(), e, parseTerm()); 740 break; 741 case REM: 742 e = new RemainderExpression(scan(), e, parseTerm()); 743 break; 744 case LSHIFT: 745 e = new ShiftLeftExpression(scan(), e, parseTerm()); 746 break; 747 case RSHIFT: 748 e = new ShiftRightExpression(scan(), e, parseTerm()); 749 break; 750 case URSHIFT: 751 e = new UnsignedShiftRightExpression(scan(), e, parseTerm()); 752 break; 753 case LT: 754 e = new LessExpression(scan(), e, parseTerm()); 755 break; 756 case LE: 757 e = new LessOrEqualExpression(scan(), e, parseTerm()); 758 break; 759 case GT: 760 e = new GreaterExpression(scan(), e, parseTerm()); 761 break; 762 case GE: 763 e = new GreaterOrEqualExpression(scan(), e, parseTerm()); 764 break; 765 case EQ: 766 e = new EqualExpression(scan(), e, parseTerm()); 767 break; 768 case NE: 769 e = new NotEqualExpression(scan(), e, parseTerm()); 770 break; 771 case BITAND: 772 e = new BitAndExpression(scan(), e, parseTerm()); 773 break; 774 case BITXOR: 775 e = new BitXorExpression(scan(), e, parseTerm()); 776 break; 777 case BITOR: 778 e = new BitOrExpression(scan(), e, parseTerm()); 779 break; 780 case AND: 781 e = new AndExpression(scan(), e, parseTerm()); 782 break; 783 case OR: 784 e = new OrExpression(scan(), e, parseTerm()); 785 break; 786 case ASSIGN: 787 e = new AssignExpression(scan(), e, parseTerm()); 788 break; 789 case ASGMUL: 790 e = new AssignMultiplyExpression(scan(), e, parseTerm()); 791 break; 792 case ASGDIV: 793 e = new AssignDivideExpression(scan(), e, parseTerm()); 794 break; 795 case ASGREM: 796 e = new AssignRemainderExpression(scan(), e, parseTerm()); 797 break; 798 case ASGADD: 799 e = new AssignAddExpression(scan(), e, parseTerm()); 800 break; 801 case ASGSUB: 802 e = new AssignSubtractExpression(scan(), e, parseTerm()); 803 break; 804 case ASGLSHIFT: 805 e = new AssignShiftLeftExpression(scan(), e, parseTerm()); 806 break; 807 case ASGRSHIFT: 808 e = new AssignShiftRightExpression(scan(), e, parseTerm()); 809 break; 810 case ASGURSHIFT: 811 e = new AssignUnsignedShiftRightExpression(scan(), e, parseTerm()); 812 break; 813 case ASGBITAND: 814 e = new AssignBitAndExpression(scan(), e, parseTerm()); 815 break; 816 case ASGBITOR: 817 e = new AssignBitOrExpression(scan(), e, parseTerm()); 818 break; 819 case ASGBITXOR: 820 e = new AssignBitXorExpression(scan(), e, parseTerm()); 821 break; 822 case QUESTIONMARK: { 823 long p = scan(); 824 Expression second = parseExpression(); 825 expect(COLON); 826 Expression third = parseExpression(); 827 828 // The grammar in the JLS does not allow assignment 829 // expressions as the third part of a ?: expression. 830 // Even though javac has no trouble parsing this, 831 // check for this case and signal an error. 832 // (fix for bug 4092958) 833 if (third instanceof AssignExpression 834 || third instanceof AssignOpExpression) { 835 env.error(third.getWhere(), "assign.in.conditionalexpr"); 836 } 837 838 e = new ConditionalExpression(p, e, second, third); 839 break; 840 } 841 842 default: 843 return null; // mark end of binary expressions 844 } 845 } 846 return e; // return more binary expression stuff 847 } 848 849 /** 850 * Recover after a syntax error in a statement. This involves 851 * discarding tokens until EOF or a possible continuation is 852 * encountered. 853 */ 854 protected boolean recoverStatement() throws SyntaxError, IOException { 855 while (true) { 856 switch (token) { 857 case EOF: 858 case RBRACE: 859 case LBRACE: 860 case IF: 861 case FOR: 862 case WHILE: 863 case DO: 864 case TRY: 865 case CATCH: 866 case FINALLY: 867 case BREAK: 868 case CONTINUE: 869 case RETURN: 870 // begin of a statement, return 871 return true; 872 873 case VOID: 874 case STATIC: 875 case PUBLIC: 876 case PRIVATE: 877 case SYNCHRONIZED: 878 case INTERFACE: 879 case CLASS: 880 case TRANSIENT: 881 // begin of something outside a statement, panic some more 882 expect(RBRACE); 883 return false; 884 885 case LPAREN: 886 match(LPAREN, RPAREN); 887 scan(); 888 break; 889 890 case LSQBRACKET: 891 match(LSQBRACKET, RSQBRACKET); 892 scan(); 893 break; 894 895 default: 896 // don't know what to do, skip 897 scan(); 898 break; 899 } 900 } 901 } 902 903 /** 904 * Parse declaration, called after the type expression 905 * has been parsed and the current token is IDENT. 906 */ 907 protected Statement parseDeclaration(long p, int mod, Expression type) throws SyntaxError, IOException { 908 int i = argIndex; 909 if (token == IDENT) { 910 addArgument(new VarDeclarationStatement(pos, parseExpression())); 911 while (token == COMMA) { 912 scan(); 913 addArgument(new VarDeclarationStatement(pos, parseExpression())); 914 } 915 } 916 return new DeclarationStatement(p, mod, type, statArgs(i)); 917 } 918 919 /** 920 * Check if an expression is a legal toplevel expression. 921 * Only method, inc, dec, and new expression are allowed. 922 */ 923 protected void topLevelExpression(Expression e) { 924 switch (e.getOp()) { 925 case ASSIGN: 926 case ASGMUL: 927 case ASGDIV: 928 case ASGREM: 929 case ASGADD: 930 case ASGSUB: 931 case ASGLSHIFT: 932 case ASGRSHIFT: 933 case ASGURSHIFT: 934 case ASGBITAND: 935 case ASGBITOR: 936 case ASGBITXOR: 937 case PREINC: 938 case PREDEC: 939 case POSTINC: 940 case POSTDEC: 941 case METHOD: 942 case NEWINSTANCE: 943 return; 944 } 945 env.error(e.getWhere(), "invalid.expr"); 946 } 947 948 /** 949 * Parse a statement. 950 */ 951 protected Statement parseStatement() throws SyntaxError, IOException { 952 switch (token) { 953 case SEMICOLON: 954 return new CompoundStatement(scan(), new Statement[0]); 955 956 case LBRACE: 957 return parseBlockStatement(); 958 959 case IF: { 960 // if-statement: if (expr) stat 961 // if-statement: if (expr) stat else stat 962 long p = scan(); 963 964 expect(LPAREN); 965 Expression c = parseExpression(); 966 expect(RPAREN); 967 Statement t = parseStatement(); 968 if (token == ELSE) { 969 scan(); 970 return new IfStatement(p, c, t, parseStatement()); 971 } else { 972 return new IfStatement(p, c, t, null); 973 } 974 } 975 976 case ELSE: { 977 // else-statement: else stat 978 env.error(scan(), "else.without.if"); 979 return parseStatement(); 980 } 981 982 case FOR: { 983 // for-statement: for (decl-expr? ; expr? ; expr?) stat 984 long p = scan(); 985 Statement init = null; 986 Expression cond = null, inc = null; 987 988 expect(LPAREN); 989 if (token != SEMICOLON) { 990 long p2 = pos; 991 int mod = parseModifiers(M_FINAL); 992 Expression e = parseExpression(); 993 994 if (token == IDENT) { 995 init = parseDeclaration(p2, mod, e); 996 } else { 997 if (mod != 0) { 998 expect(IDENT); // should have been a declaration 999 } 1000 topLevelExpression(e); 1001 while (token == COMMA) { 1002 long p3 = scan(); 1003 Expression e2 = parseExpression(); 1004 topLevelExpression(e2); 1005 e = new CommaExpression(p3, e, e2); 1006 } 1007 init = new ExpressionStatement(p2, e); 1008 } 1009 } 1010 expect(SEMICOLON); 1011 if (token != SEMICOLON) { 1012 cond = parseExpression(); 1013 } 1014 expect(SEMICOLON); 1015 if (token != RPAREN) { 1016 inc = parseExpression(); 1017 topLevelExpression(inc); 1018 while (token == COMMA) { 1019 long p2 = scan(); 1020 Expression e2 = parseExpression(); 1021 topLevelExpression(e2); 1022 inc = new CommaExpression(p2, inc, e2); 1023 } 1024 } 1025 expect(RPAREN); 1026 return new ForStatement(p, init, cond, inc, parseStatement()); 1027 } 1028 1029 case WHILE: { 1030 // while-statement: while (expr) stat 1031 long p = scan(); 1032 1033 expect(LPAREN); 1034 Expression cond = parseExpression(); 1035 expect(RPAREN); 1036 return new WhileStatement(p, cond, parseStatement()); 1037 } 1038 1039 case DO: { 1040 // do-statement: do stat while (expr) 1041 long p = scan(); 1042 1043 Statement body = parseStatement(); 1044 expect(WHILE); 1045 expect(LPAREN); 1046 Expression cond = parseExpression(); 1047 expect(RPAREN); 1048 expect(SEMICOLON); 1049 return new DoStatement(p, body, cond); 1050 } 1051 1052 case BREAK: { 1053 // break-statement: break ; 1054 long p = scan(); 1055 Identifier label = null; 1056 1057 if (token == IDENT) { 1058 label = scanner.idValue; 1059 scan(); 1060 } 1061 expect(SEMICOLON); 1062 return new BreakStatement(p, label); 1063 } 1064 1065 case CONTINUE: { 1066 // continue-statement: continue ; 1067 long p = scan(); 1068 Identifier label = null; 1069 1070 if (token == IDENT) { 1071 label = scanner.idValue; 1072 scan(); 1073 } 1074 expect(SEMICOLON); 1075 return new ContinueStatement(p, label); 1076 } 1077 1078 case RETURN: { 1079 // return-statement: return ; 1080 // return-statement: return expr ; 1081 long p = scan(); 1082 Expression e = null; 1083 1084 if (token != SEMICOLON) { 1085 e = parseExpression(); 1086 } 1087 expect(SEMICOLON); 1088 return new ReturnStatement(p, e); 1089 } 1090 1091 case SWITCH: { 1092 // switch statement: switch ( expr ) stat 1093 long p = scan(); 1094 int i = argIndex; 1095 1096 expect(LPAREN); 1097 Expression e = parseExpression(); 1098 expect(RPAREN); 1099 expect(LBRACE); 1100 1101 while ((token != EOF) && (token != RBRACE)) { 1102 int j = argIndex; 1103 try { 1104 switch (token) { 1105 case CASE: 1106 // case-statement: case expr: 1107 addArgument(new CaseStatement(scan(), parseExpression())); 1108 expect(COLON); 1109 break; 1110 1111 case DEFAULT: 1112 // default-statement: default: 1113 addArgument(new CaseStatement(scan(), null)); 1114 expect(COLON); 1115 break; 1116 1117 default: 1118 addArgument(parseStatement()); 1119 break; 1120 } 1121 } catch (SyntaxError ee) { 1122 argIndex = j; 1123 if (!recoverStatement()) { 1124 throw ee; 1125 } 1126 } 1127 } 1128 expect(RBRACE); 1129 return new SwitchStatement(p, e, statArgs(i)); 1130 } 1131 1132 case CASE: { 1133 // case-statement: case expr : stat 1134 env.error(pos, "case.without.switch"); 1135 while (token == CASE) { 1136 scan(); 1137 parseExpression(); 1138 expect(COLON); 1139 } 1140 return parseStatement(); 1141 } 1142 1143 case DEFAULT: { 1144 // default-statement: default : stat 1145 env.error(pos, "default.without.switch"); 1146 scan(); 1147 expect(COLON); 1148 return parseStatement(); 1149 } 1150 1151 case TRY: { 1152 // try-statement: try stat catch (type-expr ident) stat finally stat 1153 long p = scan(); 1154 Statement init = null; // try-object specification 1155 int i = argIndex; 1156 boolean catches = false; 1157 1158 if (false && token == LPAREN) { 1159 expect(LPAREN); 1160 long p2 = pos; 1161 int mod = parseModifiers(M_FINAL); 1162 Expression e = parseExpression(); 1163 1164 if (token == IDENT) { 1165 init = parseDeclaration(p2, mod, e); 1166 // leave check for try (T x, y) for semantic phase 1167 } else { 1168 if (mod != 0) { 1169 expect(IDENT); // should have been a declaration 1170 } 1171 init = new ExpressionStatement(p2, e); 1172 } 1173 expect(RPAREN); 1174 } 1175 1176 Statement s = parseBlockStatement(); 1177 1178 if (init != null) { 1179 // s = new FinallyStatement(p, init, s, 0); 1180 } 1181 1182 while (token == CATCH) { 1183 long pp = pos; 1184 expect(CATCH); 1185 expect(LPAREN); 1186 int mod = parseModifiers(M_FINAL); 1187 Expression t = parseExpression(); 1188 IdentifierToken id = scanner.getIdToken(); 1189 expect(IDENT); 1190 id.modifiers = mod; 1191 // We only catch Throwable's, so this is no longer required 1192 // while (token == LSQBRACKET) { 1193 // t = new ArrayAccessExpression(scan(), t, null); 1194 // expect(RSQBRACKET); 1195 // } 1196 expect(RPAREN); 1197 addArgument(new CatchStatement(pp, t, id, parseBlockStatement())); 1198 catches = true; 1199 } 1200 1201 if (catches) 1202 s = new TryStatement(p, s, statArgs(i)); 1203 1204 if (token == FINALLY) { 1205 scan(); 1206 return new FinallyStatement(p, s, parseBlockStatement()); 1207 } else if (catches || init != null) { 1208 return s; 1209 } else { 1210 env.error(pos, "try.without.catch.finally"); 1211 return new TryStatement(p, s, null); 1212 } 1213 } 1214 1215 case CATCH: { 1216 // catch-statement: catch (expr ident) stat finally stat 1217 env.error(pos, "catch.without.try"); 1218 1219 Statement s; 1220 do { 1221 scan(); 1222 expect(LPAREN); 1223 parseModifiers(M_FINAL); 1224 parseExpression(); 1225 expect(IDENT); 1226 expect(RPAREN); 1227 s = parseBlockStatement(); 1228 } while (token == CATCH); 1229 1230 if (token == FINALLY) { 1231 scan(); 1232 s = parseBlockStatement(); 1233 } 1234 return s; 1235 } 1236 1237 case FINALLY: { 1238 // finally-statement: finally stat 1239 env.error(pos, "finally.without.try"); 1240 scan(); 1241 return parseBlockStatement(); 1242 } 1243 1244 case THROW: { 1245 // throw-statement: throw expr; 1246 long p = scan(); 1247 Expression e = parseExpression(); 1248 expect(SEMICOLON); 1249 return new ThrowStatement(p, e); 1250 } 1251 1252 case GOTO: { 1253 long p = scan(); 1254 expect(IDENT); 1255 expect(SEMICOLON); 1256 env.error(p, "not.supported", "goto"); 1257 return new CompoundStatement(p, new Statement[0]); 1258 } 1259 1260 case SYNCHRONIZED: { 1261 // synchronized-statement: synchronized (expr) stat 1262 long p = scan(); 1263 expect(LPAREN); 1264 Expression e = parseExpression(); 1265 expect(RPAREN); 1266 return new SynchronizedStatement(p, e, parseBlockStatement()); 1267 } 1268 1269 case INTERFACE: 1270 case CLASS: 1271 // Inner class. 1272 return parseLocalClass(0); 1273 1274 case CONST: 1275 case ABSTRACT: 1276 case FINAL: 1277 case STRICTFP: { 1278 // a declaration of some sort 1279 long p = pos; 1280 1281 // A class which is local to a block is not a member, and so 1282 // cannot be public, private, protected, or static. It is in 1283 // effect private to the block, since it cannot be used outside 1284 // its scope. 1285 // 1286 // However, any class (if it has a name) can be declared final, 1287 // abstract, or strictfp. 1288 int mod = parseModifiers(M_FINAL | M_ABSTRACT 1289 | M_STRICTFP ); 1290 1291 switch (token) { 1292 case INTERFACE: 1293 case CLASS: 1294 return parseLocalClass(mod); 1295 1296 case BOOLEAN: 1297 case BYTE: 1298 case CHAR: 1299 case SHORT: 1300 case INT: 1301 case LONG: 1302 case FLOAT: 1303 case DOUBLE: 1304 case IDENT: { 1305 if ((mod & (M_ABSTRACT | M_STRICTFP )) != 0) { 1306 mod &= ~ (M_ABSTRACT | M_STRICTFP ); 1307 expect(CLASS); 1308 } 1309 Expression e = parseExpression(); 1310 if (token != IDENT) { 1311 expect(IDENT); 1312 } 1313 // declaration: final expr expr 1314 Statement s = parseDeclaration(p, mod, e); 1315 expect(SEMICOLON); 1316 return s; 1317 } 1318 1319 default: 1320 env.error(pos, "type.expected"); 1321 throw new SyntaxError(); 1322 } 1323 } 1324 1325 case VOID: 1326 case STATIC: 1327 case PUBLIC: 1328 case PRIVATE: 1329 case TRANSIENT: 1330 // This is the start of something outside a statement 1331 env.error(pos, "statement.expected"); 1332 throw new SyntaxError(); 1333 } 1334 1335 long p = pos; 1336 Expression e = parseExpression(); 1337 1338 if (token == IDENT) { 1339 // declaration: expr expr 1340 Statement s = parseDeclaration(p, 0, e); 1341 expect(SEMICOLON); 1342 return s; 1343 } 1344 if (token == COLON) { 1345 // label: id: stat 1346 scan(); 1347 Statement s = parseStatement(); 1348 s.setLabel(env, e); 1349 return s; 1350 } 1351 1352 // it was just an expression... 1353 topLevelExpression(e); 1354 expect(SEMICOLON); 1355 return new ExpressionStatement(p, e); 1356 } 1357 1358 protected Statement parseBlockStatement() throws SyntaxError, IOException { 1359 // compound statement: { stat1 stat2 ... statn } 1360 if (token != LBRACE) { 1361 // We're expecting a block statement. But we'll probably do the 1362 // least damage if we try to parse a normal statement instead. 1363 env.error(scanner.prevPos, "token.expected", opNames[LBRACE]); 1364 return parseStatement(); 1365 } 1366 long p = scan(); 1367 int i = argIndex; 1368 while ((token != EOF) && (token != RBRACE)) { 1369 int j = argIndex; 1370 try { 1371 addArgument(parseStatement()); 1372 } catch (SyntaxError e) { 1373 argIndex = j; 1374 if (!recoverStatement()) { 1375 throw e; 1376 } 1377 } 1378 } 1379 1380 expect(RBRACE); 1381 return new CompoundStatement(p, statArgs(i)); 1382 } 1383 1384 1385 /** 1386 * Parse an identifier. ie: a.b.c returns "a.b.c" 1387 * If star is true then "a.b.*" is allowed. 1388 * The return value encodes both the identifier and its location. 1389 */ 1390 protected IdentifierToken parseName(boolean star) throws SyntaxError, IOException { 1391 IdentifierToken res = scanner.getIdToken(); 1392 expect(IDENT); 1393 1394 if (token != FIELD) { 1395 return res; 1396 } 1397 1398 StringBuilder sb = new StringBuilder(res.id.toString()); 1399 1400 while (token == FIELD) { 1401 scan(); 1402 if ((token == MUL) && star) { 1403 scan(); 1404 sb.append(".*"); 1405 break; 1406 } 1407 1408 sb.append('.'); 1409 if (token == IDENT) { 1410 sb.append(scanner.idValue); 1411 } 1412 expect(IDENT); 1413 } 1414 1415 res.id = Identifier.lookup(sb.toString()); 1416 return res; 1417 } 1418 /** 1419 * @deprecated 1420 * @see #parseName 1421 */ 1422 @Deprecated 1423 protected Identifier parseIdentifier(boolean star) throws SyntaxError, IOException { 1424 return parseName(star).id; 1425 } 1426 1427 /** 1428 * Parse a type expression, this results in a Type. 1429 * The parse includes trailing array brackets. 1430 */ 1431 protected Type parseType() throws SyntaxError, IOException { 1432 Type t; 1433 1434 switch (token) { 1435 case IDENT: 1436 t = Type.tClass(parseName(false).id); 1437 break; 1438 case VOID: 1439 scan(); 1440 t = Type.tVoid; 1441 break; 1442 case BOOLEAN: 1443 scan(); 1444 t = Type.tBoolean; 1445 break; 1446 case BYTE: 1447 scan(); 1448 t = Type.tByte; 1449 break; 1450 case CHAR: 1451 scan(); 1452 t = Type.tChar; 1453 break; 1454 case SHORT: 1455 scan(); 1456 t = Type.tShort; 1457 break; 1458 case INT: 1459 scan(); 1460 t = Type.tInt; 1461 break; 1462 case FLOAT: 1463 scan(); 1464 t = Type.tFloat; 1465 break; 1466 case LONG: 1467 scan(); 1468 t = Type.tLong; 1469 break; 1470 case DOUBLE: 1471 scan(); 1472 t = Type.tDouble; 1473 break; 1474 default: 1475 env.error(pos, "type.expected"); 1476 throw new SyntaxError(); 1477 } 1478 return parseArrayBrackets(t); 1479 } 1480 1481 /** 1482 * Parse the tail of a type expression, which might be array brackets. 1483 * Return the given type, as possibly modified by the suffix. 1484 */ 1485 protected Type parseArrayBrackets(Type t) throws SyntaxError, IOException { 1486 1487 // Parse []'s 1488 while (token == LSQBRACKET) { 1489 scan(); 1490 if (token != RSQBRACKET) { 1491 env.error(pos, "array.dim.in.decl"); 1492 parseExpression(); 1493 } 1494 expect(RSQBRACKET); 1495 t = Type.tArray(t); 1496 } 1497 return t; 1498 } 1499 1500 /* 1501 * Dealing with argument lists, I'm not using 1502 * Vector for efficiency. 1503 */ 1504 1505 private int aCount = 0; 1506 private Type aTypes[] = new Type[8]; 1507 private IdentifierToken aNames[] = new IdentifierToken[aTypes.length]; 1508 1509 private void addArgument(int mod, Type t, IdentifierToken nm) { 1510 nm.modifiers = mod; 1511 if (aCount >= aTypes.length) { 1512 Type newATypes[] = new Type[aCount * 2]; 1513 System.arraycopy(aTypes, 0, newATypes, 0, aCount); 1514 aTypes = newATypes; 1515 IdentifierToken newANames[] = new IdentifierToken[aCount * 2]; 1516 System.arraycopy(aNames, 0, newANames, 0, aCount); 1517 aNames = newANames; 1518 } 1519 aTypes[aCount] = t; 1520 aNames[aCount++] = nm; 1521 } 1522 1523 /** 1524 * Parse a possibly-empty sequence of modifier keywords. 1525 * Return the resulting bitmask. 1526 * Diagnose repeated modifiers, but make no other checks. 1527 * Only modifiers mentioned in the given bitmask are scanned; 1528 * an unmatched modifier must be handled by the caller. 1529 */ 1530 protected int parseModifiers(int mask) throws IOException { 1531 int mod = 0; 1532 while (true) { 1533 if (token==CONST) { 1534 // const isn't in java, but handle a common C++ usage gently 1535 env.error(pos, "not.supported", "const"); 1536 scan(); 1537 } 1538 int nextmod = 0; 1539 switch (token) { 1540 case PRIVATE: nextmod = M_PRIVATE; break; 1541 case PUBLIC: nextmod = M_PUBLIC; break; 1542 case PROTECTED: nextmod = M_PROTECTED; break; 1543 case STATIC: nextmod = M_STATIC; break; 1544 case TRANSIENT: nextmod = M_TRANSIENT; break; 1545 case FINAL: nextmod = M_FINAL; break; 1546 case ABSTRACT: nextmod = M_ABSTRACT; break; 1547 case NATIVE: nextmod = M_NATIVE; break; 1548 case VOLATILE: nextmod = M_VOLATILE; break; 1549 case SYNCHRONIZED: nextmod = M_SYNCHRONIZED; break; 1550 case STRICTFP: nextmod = M_STRICTFP; break; 1551 } 1552 if ((nextmod & mask) == 0) { 1553 break; 1554 } 1555 if ((nextmod & mod) != 0) { 1556 env.error(pos, "repeated.modifier"); 1557 } 1558 mod |= nextmod; 1559 scan(); 1560 } 1561 return mod; 1562 } 1563 1564 private ClassDefinition curClass; 1565 1566 /** 1567 * Parse a field. 1568 */ 1569 protected void parseField() throws SyntaxError, IOException { 1570 1571 // Empty fields are not allowed by the JLS but are accepted by 1572 // the compiler, and much code has come to rely on this. It has 1573 // been decided that the language will be extended to legitimize them. 1574 if (token == SEMICOLON) { 1575 // empty field 1576 scan(); 1577 return; 1578 } 1579 1580 // Optional doc comment 1581 String doc = scanner.docComment; 1582 1583 // The start of the field 1584 long p = pos; 1585 1586 // Parse the modifiers 1587 int mod = parseModifiers(MM_FIELD | MM_METHOD); 1588 1589 // Check for static initializer 1590 // ie: static { ... } 1591 // or an instance initializer (w/o the static). 1592 if ((mod == (mod & M_STATIC)) && (token == LBRACE)) { 1593 // static initializer 1594 actions.defineField(p, curClass, doc, mod, 1595 Type.tMethod(Type.tVoid), 1596 new IdentifierToken(idClassInit), null, null, 1597 parseStatement()); 1598 return; 1599 } 1600 1601 // Check for inner class 1602 if (token == CLASS || token == INTERFACE) { 1603 parseNamedClass(mod, CLASS, doc); 1604 return; 1605 } 1606 1607 // Parse the type 1608 p = pos; 1609 Type t = parseType(); 1610 IdentifierToken id = null; 1611 1612 // Check that the type is followed by an Identifier 1613 // (the name of the method or the first variable), 1614 // otherwise it is a constructor. 1615 switch (token) { 1616 case IDENT: 1617 id = scanner.getIdToken(); 1618 p = scan(); 1619 break; 1620 1621 case LPAREN: 1622 // It is a constructor 1623 id = new IdentifierToken(idInit); 1624 if ((mod & M_STRICTFP) != 0) 1625 env.error(pos, "bad.constructor.modifier"); 1626 break; 1627 1628 default: 1629 expect(IDENT); 1630 } 1631 1632 // If the next token is a left-bracket then we 1633 // are dealing with a method or constructor, otherwise it is 1634 // a list of variables 1635 if (token == LPAREN) { 1636 // It is a method or constructor declaration 1637 scan(); 1638 aCount = 0; 1639 1640 if (token != RPAREN) { 1641 // Parse argument type and identifier 1642 // (arguments (like locals) are allowed to be final) 1643 int am = parseModifiers(M_FINAL); 1644 Type at = parseType(); 1645 IdentifierToken an = scanner.getIdToken(); 1646 expect(IDENT); 1647 1648 // Parse optional array specifier, ie: a[][] 1649 at = parseArrayBrackets(at); 1650 addArgument(am, at, an); 1651 1652 // If the next token is a comma then there are 1653 // more arguments 1654 while (token == COMMA) { 1655 // Parse argument type and identifier 1656 scan(); 1657 am = parseModifiers(M_FINAL); 1658 at = parseType(); 1659 an = scanner.getIdToken(); 1660 expect(IDENT); 1661 1662 // Parse optional array specifier, ie: a[][] 1663 at = parseArrayBrackets(at); 1664 addArgument(am, at, an); 1665 } 1666 } 1667 expect(RPAREN); 1668 1669 // Parse optional array sepecifier, ie: foo()[][] 1670 t = parseArrayBrackets(t); 1671 1672 // copy arguments 1673 Type atypes[] = new Type[aCount]; 1674 System.arraycopy(aTypes, 0, atypes, 0, aCount); 1675 1676 IdentifierToken anames[] = new IdentifierToken[aCount]; 1677 System.arraycopy(aNames, 0, anames, 0, aCount); 1678 1679 // Construct the type signature 1680 t = Type.tMethod(t, atypes); 1681 1682 // Parse and ignore throws clause 1683 IdentifierToken exp[] = null; 1684 if (token == THROWS) { 1685 Vector<IdentifierToken> v = new Vector<>(); 1686 scan(); 1687 v.addElement(parseName(false)); 1688 while (token == COMMA) { 1689 scan(); 1690 v.addElement(parseName(false)); 1691 } 1692 1693 exp = new IdentifierToken[v.size()]; 1694 v.copyInto(exp); 1695 } 1696 1697 // Check if it is a method definition or a method declaration 1698 // ie: foo() {...} or foo(); 1699 switch (token) { 1700 case LBRACE: // It's a method definition 1701 1702 // Set the state of FP strictness for the body of the method 1703 int oldFPstate = FPstate; 1704 if ((mod & M_STRICTFP)!=0) { 1705 FPstate = M_STRICTFP; 1706 } else { 1707 mod |= FPstate & M_STRICTFP; 1708 } 1709 1710 actions.defineField(p, curClass, doc, mod, t, id, 1711 anames, exp, parseStatement()); 1712 1713 FPstate = oldFPstate; 1714 1715 break; 1716 1717 case SEMICOLON: 1718 scan(); 1719 actions.defineField(p, curClass, doc, mod, t, id, 1720 anames, exp, null); 1721 break; 1722 1723 default: 1724 // really expected a statement body here 1725 if ((mod & (M_NATIVE | M_ABSTRACT)) == 0) { 1726 expect(LBRACE); 1727 } else { 1728 expect(SEMICOLON); 1729 } 1730 } 1731 return; 1732 } 1733 1734 // It is a list of instance variables 1735 while (true) { 1736 p = pos; // get the current position 1737 // parse the array brackets (if any) 1738 // ie: var[][][] 1739 Type vt = parseArrayBrackets(t); 1740 1741 // Parse the optional initializer 1742 Node init = null; 1743 if (token == ASSIGN) { 1744 scan(); 1745 init = parseExpression(); 1746 } 1747 1748 // Define the variable 1749 actions.defineField(p, curClass, doc, mod, vt, id, 1750 null, null, init); 1751 1752 // If the next token is a comma, then there is more 1753 if (token != COMMA) { 1754 expect(SEMICOLON); 1755 return; 1756 } 1757 scan(); 1758 1759 // The next token must be an identifier 1760 id = scanner.getIdToken(); 1761 expect(IDENT); 1762 } 1763 } 1764 1765 /** 1766 * Recover after a syntax error in a field. This involves 1767 * discarding tokens until an EOF or a possible legal 1768 * continuation is encountered. 1769 */ 1770 protected void recoverField(ClassDefinition newClass) throws SyntaxError, IOException { 1771 while (true) { 1772 switch (token) { 1773 case EOF: 1774 case STATIC: 1775 case FINAL: 1776 case PUBLIC: 1777 case PRIVATE: 1778 case SYNCHRONIZED: 1779 case TRANSIENT: 1780 1781 case VOID: 1782 case BOOLEAN: 1783 case BYTE: 1784 case CHAR: 1785 case SHORT: 1786 case INT: 1787 case FLOAT: 1788 case LONG: 1789 case DOUBLE: 1790 // possible begin of a field, continue 1791 return; 1792 1793 case LBRACE: 1794 match(LBRACE, RBRACE); 1795 scan(); 1796 break; 1797 1798 case LPAREN: 1799 match(LPAREN, RPAREN); 1800 scan(); 1801 break; 1802 1803 case LSQBRACKET: 1804 match(LSQBRACKET, RSQBRACKET); 1805 scan(); 1806 break; 1807 1808 case RBRACE: 1809 case INTERFACE: 1810 case CLASS: 1811 case IMPORT: 1812 case PACKAGE: 1813 // begin of something outside a class, panic more 1814 actions.endClass(pos, newClass); 1815 throw new SyntaxError(); 1816 1817 default: 1818 // don't know what to do, skip 1819 scan(); 1820 break; 1821 } 1822 } 1823 } 1824 1825 /** 1826 * Parse a top-level class or interface declaration. 1827 */ 1828 protected void parseClass() throws SyntaxError, IOException { 1829 String doc = scanner.docComment; 1830 1831 // Parse the modifiers. 1832 int mod = parseModifiers(MM_CLASS | MM_MEMBER); 1833 1834 parseNamedClass(mod, PACKAGE, doc); 1835 } 1836 1837 // Current strict/default state of floating point. This is 1838 // set and reset with a stack discipline around methods and named 1839 // classes. Only M_STRICTFP may be set in this word. try... 1840 // finally is not needed to protect setting and resetting because 1841 // there are no error messages based on FPstate. 1842 private int FPstate = 0; 1843 1844 /** 1845 * Parse a block-local class or interface declaration. 1846 */ 1847 protected Statement parseLocalClass(int mod) throws SyntaxError, IOException { 1848 long p = pos; 1849 ClassDefinition body = parseNamedClass(M_LOCAL | mod, STAT, null); 1850 Statement ds[] = { 1851 new VarDeclarationStatement(p, new LocalMember(body), null) 1852 }; 1853 Expression type = new TypeExpression(p, body.getType()); 1854 return new DeclarationStatement(p, 0, type, ds); 1855 } 1856 1857 /** 1858 * Parse a named class or interface declaration, 1859 * starting at "class" or "interface". 1860 * @arg ctx Syntactic context of the class, one of {PACKAGE CLASS STAT EXPR}. 1861 */ 1862 protected ClassDefinition parseNamedClass(int mod, int ctx, String doc) throws SyntaxError, IOException { 1863 // Parse class/interface 1864 switch (token) { 1865 case INTERFACE: 1866 scan(); 1867 mod |= M_INTERFACE; 1868 break; 1869 1870 case CLASS: 1871 scan(); 1872 break; 1873 1874 default: 1875 env.error(pos, "class.expected"); 1876 break; 1877 } 1878 1879 int oldFPstate = FPstate; 1880 if ((mod & M_STRICTFP)!=0) { 1881 FPstate = M_STRICTFP; 1882 } else { 1883 // The & (...) isn't really necessary here because we do maintain 1884 // the invariant that FPstate has no extra bits set. 1885 mod |= FPstate & M_STRICTFP; 1886 } 1887 1888 // Parse the class name 1889 IdentifierToken nm = scanner.getIdToken(); 1890 long p = pos; 1891 expect(IDENT); 1892 1893 Vector<IdentifierToken> ext = new Vector<>(); 1894 Vector<IdentifierToken> impl = new Vector<>(); 1895 parseInheritance(ext, impl); 1896 1897 ClassDefinition tmp = parseClassBody(nm, mod, ctx, doc, ext, impl, p); 1898 1899 FPstate = oldFPstate; 1900 1901 return tmp; 1902 } 1903 1904 protected void parseInheritance(Vector<IdentifierToken> ext, Vector<IdentifierToken> impl) throws SyntaxError, IOException { 1905 // Parse extends clause 1906 if (token == EXTENDS) { 1907 scan(); 1908 ext.addElement(parseName(false)); 1909 while (token == COMMA) { 1910 scan(); 1911 ext.addElement(parseName(false)); 1912 } 1913 } 1914 1915 // Parse implements clause 1916 if (token == IMPLEMENTS) { 1917 scan(); 1918 impl.addElement(parseName(false)); 1919 while (token == COMMA) { 1920 scan(); 1921 impl.addElement(parseName(false)); 1922 } 1923 } 1924 } 1925 1926 /** 1927 * Parse the body of a class or interface declaration, 1928 * starting at the left brace. 1929 */ 1930 protected ClassDefinition parseClassBody(IdentifierToken nm, int mod, 1931 int ctx, String doc, 1932 Vector<IdentifierToken> ext, Vector<IdentifierToken> impl, long p 1933 ) throws SyntaxError, IOException { 1934 // Decide which is the super class 1935 IdentifierToken sup = null; 1936 if ((mod & M_INTERFACE) != 0) { 1937 if (impl.size() > 0) { 1938 env.error(impl.elementAt(0).getWhere(), 1939 "intf.impl.intf"); 1940 } 1941 impl = ext; 1942 } else { 1943 if (ext.size() > 0) { 1944 if (ext.size() > 1) { 1945 env.error(ext.elementAt(1).getWhere(), 1946 "multiple.inherit"); 1947 } 1948 sup = ext.elementAt(0); 1949 } 1950 } 1951 1952 ClassDefinition oldClass = curClass; 1953 1954 // Begin a new class 1955 IdentifierToken implids[] = new IdentifierToken[impl.size()]; 1956 impl.copyInto(implids); 1957 ClassDefinition newClass = 1958 actions.beginClass(p, doc, mod, nm, sup, implids); 1959 1960 // Parse fields 1961 expect(LBRACE); 1962 while ((token != EOF) && (token != RBRACE)) { 1963 try { 1964 curClass = newClass; 1965 parseField(); 1966 } catch (SyntaxError e) { 1967 recoverField(newClass); 1968 } finally { 1969 curClass = oldClass; 1970 } 1971 } 1972 expect(RBRACE); 1973 1974 // End the class 1975 actions.endClass(scanner.prevPos, newClass); 1976 return newClass; 1977 } 1978 1979 /** 1980 * Recover after a syntax error in the file. 1981 * This involves discarding tokens until an EOF 1982 * or a possible legal continuation is encountered. 1983 */ 1984 protected void recoverFile() throws IOException { 1985 while (true) { 1986 switch (token) { 1987 case CLASS: 1988 case INTERFACE: 1989 // Start of a new source file statement, continue 1990 return; 1991 1992 case LBRACE: 1993 match(LBRACE, RBRACE); 1994 scan(); 1995 break; 1996 1997 case LPAREN: 1998 match(LPAREN, RPAREN); 1999 scan(); 2000 break; 2001 2002 case LSQBRACKET: 2003 match(LSQBRACKET, RSQBRACKET); 2004 scan(); 2005 break; 2006 2007 case EOF: 2008 return; 2009 2010 default: 2011 // Don't know what to do, skip 2012 scan(); 2013 break; 2014 } 2015 } 2016 } 2017 2018 /** 2019 * Parse an Java file. 2020 */ 2021 public void parseFile() { 2022 try { 2023 try { 2024 if (token == PACKAGE) { 2025 // Package statement 2026 long p = scan(); 2027 IdentifierToken id = parseName(false); 2028 expect(SEMICOLON); 2029 actions.packageDeclaration(p, id); 2030 } 2031 } catch (SyntaxError e) { 2032 recoverFile(); 2033 } 2034 while (token == IMPORT) { 2035 try{ 2036 // Import statement 2037 long p = scan(); 2038 IdentifierToken id = parseName(true); 2039 expect(SEMICOLON); 2040 if (id.id.getName().equals(idStar)) { 2041 id.id = id.id.getQualifier(); 2042 actions.importPackage(p, id); 2043 } else { 2044 actions.importClass(p, id); 2045 } 2046 } catch (SyntaxError e) { 2047 recoverFile(); 2048 } 2049 } 2050 2051 while (token != EOF) { 2052 try { 2053 switch (token) { 2054 case FINAL: 2055 case PUBLIC: 2056 case PRIVATE: 2057 case ABSTRACT: 2058 case CLASS: 2059 case INTERFACE: 2060 case STRICTFP: 2061 // Start of a class 2062 parseClass(); 2063 break; 2064 2065 case SEMICOLON: 2066 // Bogus semicolon. 2067 // According to the JLS (7.6,19.6), a TypeDeclaration 2068 // may consist of a single semicolon, however, this 2069 // usage is discouraged (JLS 7.6). In contrast, 2070 // a FieldDeclaration may not be empty, and is flagged 2071 // as an error. See parseField above. 2072 scan(); 2073 break; 2074 2075 case EOF: 2076 // The end 2077 return; 2078 2079 default: 2080 // Oops 2081 env.error(pos, "toplevel.expected"); 2082 throw new SyntaxError(); 2083 } 2084 } catch (SyntaxError e) { 2085 recoverFile(); 2086 } 2087 } 2088 } catch (IOException e) { 2089 env.error(pos, "io.exception", env.getSource()); 2090 return; 2091 } 2092 } 2093 2094 /** 2095 * Usually <code>this.scanner == (Scanner)this</code>. 2096 * However, a delegate scanner can produce tokens for this parser, 2097 * in which case <code>(Scanner)this</code> is unused, 2098 * except for <code>this.token</code> and <code>this.pos</code> 2099 * instance variables which are filled from the real scanner 2100 * by <code>this.scan()</code> and the constructor. 2101 */ 2102 protected Scanner scanner; 2103 2104 // Design Note: We ought to disinherit Parser from Scanner. 2105 // We also should split out the interface ParserActions from 2106 // Parser, and make BatchParser implement ParserActions, 2107 // not extend Parser. This would split scanning, parsing, 2108 // and class building into distinct responsibility areas. 2109 // (Perhaps tree building could be virtualized too.) 2110 2111 public long scan() throws IOException { 2112 if (scanner != this && scanner != null) { 2113 long result = scanner.scan(); 2114 ((Scanner)this).token = scanner.token; 2115 ((Scanner)this).pos = scanner.pos; 2116 return result; 2117 } 2118 return super.scan(); 2119 } 2120 2121 public void match(int open, int close) throws IOException { 2122 if (scanner != this) { 2123 scanner.match(open, close); 2124 ((Scanner)this).token = scanner.token; 2125 ((Scanner)this).pos = scanner.pos; 2126 return; 2127 } 2128 super.match(open, close); 2129 } 2130} 2131