001 /* Copyright 2000, 2001, Compaq Computer Corporation */ 002 003 package javafe.parser; 004 005 import javafe.ast.*; 006 import javafe.util.Location; 007 import javafe.util.StackVector; 008 import javafe.util.Assert; 009 import javafe.Tool; 010 011 /** 012 * Parses java expressions. Extended by {@link javafe.parser.ParseStmt}. 013 * 014 * @see javafe.ast.ASTNode 015 * @see javafe.parser.ParseType 016 * @see javafe.parser.ParseStmt 017 */ 018 019 public abstract class ParseExpr extends ParseType 020 { 021 // ---------------------------------------------------------------------- 022 // Operator precedence parser 023 024 // We need a stack of < Expr, op, precedence, locOp > 025 // We keep it in these four parallel arrays, and resize as necessary. 026 027 private int defaultStackSize = 12; 028 029 //@ private invariant stackPtr >= -1; 030 //@ private invariant stackPtr < exprStack.length; 031 private int stackPtr = -1; // Always points to top element, if any 032 033 //@ private invariant exprStack != null; 034 //@ private invariant exprStack.length > 0; 035 //@ private invariant \typeof(exprStack) == \type(Expr[]); 036 private Expr exprStack[] = new Expr[defaultStackSize]; 037 038 //@ private invariant opStack != null; 039 //@ private invariant opStack.length == exprStack.length; 040 private int opStack[] = new int[defaultStackSize]; 041 042 //@ private invariant precedenceStack != null; 043 //@ private invariant precedenceStack.length == exprStack.length; 044 private int precedenceStack[] = new int[defaultStackSize]; 045 046 //@ private invariant locStack != null; 047 //@ private invariant locStack.length == exprStack.length; 048 private int locStack[] = new int[defaultStackSize]; 049 050 // The operator precedence parser can be extended with additional 051 // binary operators. 052 // We keep the precedence and associtivity of each operator 053 // in the following tables. The precedence is 0 for tokens that are 054 // not operators. These tables are sized as necessary. 055 056 //@ private invariant precedenceTable != null; 057 private int[] precedenceTable = new int[0]; 058 059 //@ private invariant isLeftAssocTable != null; 060 //@ private invariant isLeftAssocTable.length == precedenceTable.length; 061 private boolean[] isLeftAssocTable = new boolean[0]; 062 063 /** If no constructors are found in "elems", adds a default one to 064 it. If a default constructor is created, the "loc" and "locId" 065 fields of the default constructor will be set to "loc". 066 A declaration of this method is needed because class declarations 067 can be in expressions. However, the body lives in Parse.java */ 068 //@ requires loc != Location.NULL; 069 //@ requires elems != null; 070 abstract void addDefaultConstructor(TypeDeclElemVec elems, int loc, boolean specOnly); 071 072 /** Parse an element of a type declaration into "seq". 073 "keyword" should be the kind of type decl, one of CLASS or INTERFACE. 074 "containerId" should be the name of the containing type decl. 075 Lives in Parse.java; more doc can be found there. */ 076 //@ requires l != null && l.m_in != null; 077 abstract TypeDeclElem parseTypeDeclElemIntoSeqTDE(Lex l, int keyword, 078 /*@ non_null @*/ Identifier 079 containerId, 080 boolean specOnly); 081 082 /** 083 * Add an infix, binary operator to the parser with a given 084 * precedence and associativity. The precedence level must be 085 * greater than zero. The following table gives the precedence 086 * levels assigned to the built-in Java operators 087 * 088 * <center><table> 089 * <tr><td><b>Operator</b></td><td><b>Precedenc</b></td><td><b>Assoc</b></td> 090 * </tr> 091 * <tr><td>TagConstants.STAR</td><td>170</td><td>left</td></tr> 092 * <tr><td>TagConstants.DIV</td><td> 170</td><td>left</td></tr> 093 * <tr><td>TagConstants.MOD</td><td> 170</td><td>left</td></tr> 094 * <tr><td>TagConstants.ADD</td><td> 160</td><td>left</td></tr> 095 * <tr><td>TagConstants.SUB</td><td> 160</td><td>left</td></tr> 096 * <tr><td>TagConstants.LSHIFT</td><td>150</td><td>left</td></tr> 097 * <tr><td>TagConstants.RSHIFT</td><td>150</td><td>left</td></tr> 098 * <tr><td>TagConstants.URSHIFT</td><td>150</td><td>left</td></tr> 099 * <tr><td>TagConstants.GE</td><td>140</td><td>left</td></tr> 100 * <tr><td>TagConstants.GT</td><td>140</td><td>left</td></tr> 101 * <tr><td>TagConstants.LT</td><td>140</td><td>left</td></tr> 102 * <tr><td>TagConstants.LE</td><td>140</td><td>left</td></tr> 103 * <tr><td>TagConstants.INSTANCEOF</td><td>140</td><td>left</td></tr> 104 * <tr><td>TagConstants.EQ</td><td>130</td><td>left</td></tr> 105 * <tr><td>TagConstants.NE</td><td>130</td><td>left</td></tr> 106 * <tr><td>TagConstants.BITAND</td><td>120</td><td>left</td></tr> 107 * <tr><td>TagConstants.BITXOR</td><td>110</td><td>left</td></tr> 108 * <tr><td>TagConstants.BITOR</td><td>100</td><td>left</td></tr> 109 * <tr><td>TagConstants.AND</td><td>90</td><td>left</td></tr> 110 * <tr><td>TagConstants.OR</td><td>80</td><td>left</td></tr> 111 * <tr><td>TagConstants.QUESTIONMARK</td><td>70</td><td>left</td></tr> 112 * <tr><td>TagConstants.ASSIGN</td><td>60</td><td>right</td></tr> 113 * <tr><td>TagConstants.ASGMUL</td><td>60</td><td>right</td></tr> 114 * <tr><td>TagConstants.ASGDIV</td><td>60</td><td>right</td></tr> 115 * <tr><td>TagConstants.ASGREM</td><td>60</td><td>right</td></tr> 116 * <tr><td>TagConstants.ASGADD</td><td>60</td><td>right</td></tr> 117 * <tr><td>TagConstants.ASGSUB</td><td>60</td><td>right</td></tr> 118 * <tr><td>TagConstants.ASGLSHIFT</td><td>60</td><td>right</td></tr> 119 * <tr><td>TagConstants.ASGRSHIFT</td><td>60</td><td>right</td></tr> 120 * <tr><td>TagConstants.ASGURSHIFT</td><td>60</td><td>right</td></tr> 121 * <tr><td>TagConstants.ASGBITAND</td><td>60</td><td>right</td></tr> 122 * <tr><td>TagConstants.ASGBITOR</td><td>60</td><td>right</td></tr> 123 * <tr><td>TagConstants.ASGBITXOR</td><td>60</td><td>right</td></tr> 124 * </table></center> 125 * 126 * <p> (The operators <code>?</code> and <code>instanceof</code> are 127 * treated specially by the parser, but this special treatment 128 * respects the precedence levels indicated above.) 129 */ 130 131 //@ requires ttype >= 0; 132 public void addOperator(int ttype, 133 int precedence, 134 boolean isLeftAssoc) 135 { 136 137 if( precedenceTable.length <= ttype ) 138 { 139 // expand 140 int[] nuPrecedenceTable = new int[ ttype+1 ]; 141 System.arraycopy(precedenceTable, 0, nuPrecedenceTable, 0, 142 precedenceTable.length ); 143 precedenceTable = nuPrecedenceTable; 144 boolean[] nuIsLeftAssocTable = new boolean[ ttype+1 ]; 145 System.arraycopy(isLeftAssocTable, 0, nuIsLeftAssocTable, 0, 146 isLeftAssocTable.length ); 147 isLeftAssocTable = nuIsLeftAssocTable; 148 } 149 precedenceTable[ ttype ] = precedence; 150 isLeftAssocTable[ ttype ] = isLeftAssoc; 151 } 152 153 154 /** 155 * Parse an <tt>Expression</tt>. 156 * 157 * <p> Does operator-precedence parsing of a large amount of the 158 * <tt>Expression</tt> hierarchy, all the way down to 159 * <tt>UnaryExpression</tt>. 160 * 161 * <pre> 162 * Expression: 163 * UnaryExpression 164 * Expression BinaryOp Expression 165 * Expression instanceof Type 166 * Expression ? Expression : Expression 167 * 168 * BinaryOp: one of 169 * STAR / % PLUS - << >> >>> > >= < <= == != & BITOR ^ && || 170 * = *= /= %= += -= <<= >>= >>>= &= |= ^= 171 * </pre> 172 * 173 * <p> This grammar is ambiguous; the precedence parsing machinery 174 * resolves the ambiguity appropriately, according to the grammar 175 * in chapter 19 of "The Java Language Specification". 176 */ 177 178 //@ requires l != null && l.m_in != null; 179 //@ ensures \result != null; 180 public Expr parseExpression(Lex l) { 181 // Save old stack pointer, so re-enterable 182 int baseStackPtr = stackPtr; 183 184 getExpression: 185 for(;;) { 186 187 // Get a UnaryExpression 188 Expr e = parseUnaryExpression(l); 189 190 getOp: 191 for(;;) { 192 193 // Get following op 194 int op = l.ttype; 195 int locOp = l.startingLoc; 196 197 // Figure out if op really is an operator, 198 // and if so, what is its precedence 199 int precedence; 200 boolean isLeftAssoc; 201 202 if( 0 <= op && op < precedenceTable.length ) 203 { 204 precedence = precedenceTable[ op ]; 205 isLeftAssoc = isLeftAssocTable[ op ]; 206 } 207 else 208 { 209 precedence = 0; 210 isLeftAssoc = false; // dummy value 211 } 212 213 // while precedence of new token is lower than that of 214 // top operator on stack, do a reduction 215 // Combine the top stack expression, the top stack operator, 216 // and the expression e to produce a new expression e 217 218 //@ loop_invariant stackPtr < exprStack.length; 219 while( stackPtr > baseStackPtr 220 && 221 (( isLeftAssoc && precedenceStack[stackPtr] >= precedence ) 222 || 223 ( !isLeftAssoc && precedenceStack[stackPtr] > precedence ))) 224 { 225 e = BinaryExpr.make(opStack[stackPtr], 226 exprStack[stackPtr], 227 e, 228 locStack[stackPtr] ); 229 stackPtr --; 230 } 231 232 // Now deal with new operator 233 234 if( precedence == 0 ) 235 { 236 // We dont have an operator, so end of Expression 237 if( stackPtr != baseStackPtr ) 238 fail(l.startingLoc, 239 "Internal error in operator precedence parser"); 240 return e; 241 } 242 else if( op == TagConstants.INSTANCEOF ) { 243 // get ReferenceType, and reduce 244 l.getNextToken(); 245 Type t = parseType( l ); 246 e = InstanceOfExpr.make( e, t, locOp ); 247 248 // Now go to check following op 249 continue getOp; 250 } else if( op == TagConstants.QUESTIONMARK ) { 251 l.getNextToken(); 252 Expr thn = parseExpression( l ); 253 int locColon = l.startingLoc; 254 expect( l, TagConstants.COLON ); 255 Expr els = parseExpression( l ); 256 e = CondExpr.make( e, thn, els, locOp, locColon); 257 258 // Now go to check following op 259 // This will never be a proper op, 260 // so we will just pop stack, reduce and return 261 continue getOp; 262 } else { 263 l.getNextToken(); 264 // Put Expression and operator on top of the stack; 265 stackPtr++; 266 267 // check if we need to resize arrays 268 269 if( stackPtr == exprStack.length ) { 270 271 Expr exprStack2[] = new Expr[2*exprStack.length]; 272 System.arraycopy( exprStack, 0, exprStack2, 0, stackPtr); 273 exprStack = exprStack2; 274 275 int opStack2[] = new int[2*opStack.length]; 276 System.arraycopy( opStack, 0, opStack2, 0, stackPtr); 277 opStack = opStack2; 278 279 int precedenceStack2[] = new int[2*precedenceStack.length]; 280 System.arraycopy( precedenceStack, 0, precedenceStack2, 0, 281 stackPtr); 282 precedenceStack = precedenceStack2; 283 284 int locStack2[] = new int[2*locStack.length]; 285 System.arraycopy( locStack, 0, locStack2, 0, stackPtr); 286 locStack = locStack2; 287 288 } // resized 289 290 exprStack[stackPtr] = e; 291 opStack[stackPtr] = op; 292 precedenceStack[stackPtr] = precedence; 293 locStack[stackPtr] = locOp; 294 continue getExpression; 295 } 296 // We never get down to here 297 } 298 } 299 } 300 301 /********************************************************************** 302 303 Parse a <TT>UnaryExpression</TT>. 304 305 <PRE> 306 UnaryExpression: 307 PLUS UnaryExpression 308 - UnaryExpression 309 ++ UnaryExpression 310 -- UnaryExpression 311 ~ UnaryExpression 312 ! UnaryExpression 313 PrimaryExpression 314 CastExpression 315 </PRE> 316 317 A <TT>CastExpression</TT> (as opposed to a <TT>PrimaryExpression</TT>) 318 is recognised by the lookahead sequences: 319 320 <PRE> 321 LPAREN PrimitiveType 322 LPAREN Name (LSQBRACKET RSQBRACKET)* RPAREN X 323 </PRE> 324 325 where <TT>X</TT> is the first token of a <TT>UnaryExpressionNotPlusMinus</TT>, 326 cf. isStartOfUnaryExpressionNotPlusMinus(-). 327 328 */ 329 330 //@ requires l != null && l.m_in != null; 331 //@ ensures \result != null; 332 public Expr parseUnaryExpression(Lex l) { 333 Expr primary; 334 335 switch( l.ttype ) { 336 case TagConstants.SUB: { 337 int locOp = l.startingLoc; 338 l.getNextToken(); 339 if (l.ttype == TagConstants.MAX_INT_PLUS_ONE) { 340 l.getNextToken(); 341 return LiteralExpr.make(TagConstants.INTLIT, 342 new Integer(Integer.MIN_VALUE), locOp); 343 } else if (l.ttype == TagConstants.MAX_LONG_PLUS_ONE) { 344 l.getNextToken(); 345 return LiteralExpr.make(TagConstants.LONGLIT, 346 new Long(Long.MIN_VALUE), locOp); 347 } else return UnaryExpr.make(OperatorTags.UNARYSUB, 348 parseUnaryExpression(l), locOp); 349 } 350 351 case TagConstants.ADD: 352 case TagConstants.INC: case TagConstants.DEC: case TagConstants.NOT: case TagConstants.BITNOT: 353 { 354 int op = l.ttype; 355 int locOp = l.startingLoc; 356 l.getNextToken(); 357 if (op == TagConstants.ADD) op = OperatorTags.UNARYADD; 358 return UnaryExpr.make(op, parseUnaryExpression(l), locOp); 359 } 360 361 default: 362 // Need CastExpression or PrimaryExpression 363 // For CastExpression, need lookahead 364 // LPAREN PrimitiveType 365 // or 366 // LPAREN Name (LSQBRACKET RSQBRACKET)* RPAREN X 367 // where X is the first token of a UnaryExpressionNotPlusMinus, 368 // ie X is one of ~ ! Literal Id this new super LPAREN 369 // 370 // TypeModifierPragmas may appear between LSQBRACKET RSQBRACKET 371 // or after the Name. 372 if( l.ttype == TagConstants.LPAREN ) { 373 374 int i = 1; // lookahead counter 375 376 // count leading left parens: handles case for ((A))a; 377 int parenCount = 1; 378 while (l.lookahead(i) == TagConstants.LPAREN) { 379 parenCount++; 380 i++; 381 } 382 383 switch( l.lookahead(i) ) { 384 case TagConstants.IDENT: 385 { 386 // Look for Name (LSQBRACKET RSQBRACKET)* RPAREN X 387 i += 1; 388 while( l.lookahead(i) == TagConstants.FIELD && 389 l.lookahead(i+1) == TagConstants.IDENT ) 390 i+=2; 391 392 // skip over TypeModifierPragmas 393 while (l.lookahead(i) == TagConstants.TYPEMODIFIERPRAGMA) i++; 394 395 // skip over ([ TypeModifierPragma ])* 396 while(true) { 397 int temp = i; 398 if (l.lookahead(i) != TagConstants.LSQBRACKET) break; 399 i++; 400 while (l.lookahead(i) == TagConstants.TYPEMODIFIERPRAGMA) i++; 401 if (l.lookahead(i) != TagConstants.RSQBRACKET) { 402 i = temp; break; 403 } 404 i++; 405 } 406 if( l.lookahead(i) == TagConstants.RPAREN ) { 407 // Look for prefix of UnaryExpressionNotPlusMinus 408 parenCount--; 409 410 // skip over any other parens: ((A))a; 411 while (l.lookahead(i + 1) == TagConstants.RPAREN && parenCount > 0) { 412 parenCount--; 413 i++; 414 } 415 416 if (parenCount != 0) { 417 return parsePrimaryExpression(l); 418 } 419 420 if (isStartOfUnaryExpressionNotPlusMinus(l.lookahead(i + 1))) 421 return parseCastExpression(l); 422 else 423 // Not followed by UnaryExpressionNotPlusMinus prefix, 424 // so is PrimaryExpression 425 return parsePrimaryExpression(l); 426 } else { 427 // Not RPAREN, so is PrimaryExpression 428 return parsePrimaryExpression(l); 429 } 430 } 431 432 default: 433 if (isPrimitiveKeywordTag(l.lookahead(1))) 434 return parseCastExpression(l); 435 436 // Token after LPAREN not IDENT or PrimitiveType 437 return parsePrimaryExpression(l); 438 } 439 } else { 440 // Expression does not start with LPAREN 441 return parsePrimaryExpression(l); 442 } 443 } 444 } // End parseUnaryExpression 445 446 447 448 /** 449 * Determines whether the tag is the first token of a 450 * <TT>UnaryExpressionNotPlusMinus</TT>. 451 * 452 * For the default Java grammar, this amounts to is tag one of: 453 * 454 * ~ ! Literal Id this new super LPAREN 455 * 456 * However, it is expected that grammar extensions may extend 457 * this list. 458 */ 459 public boolean isStartOfUnaryExpressionNotPlusMinus(int tag) { 460 // Look for prefix of UnaryExpressionNotPlusMinus 461 switch (tag) { 462 case TagConstants.BITNOT: 463 case TagConstants.NOT: 464 465 // All literals: 466 case TagConstants.CHARLIT: case TagConstants.INTLIT: 467 case TagConstants.LONGLIT: case TagConstants.FLOATLIT: 468 case TagConstants.DOUBLELIT: case TagConstants.STRINGLIT: 469 case TagConstants.TRUE: case TagConstants.FALSE: 470 case TagConstants.NULL: 471 472 case TagConstants.IDENT: 473 case TagConstants.THIS: 474 case TagConstants.NEW: 475 case TagConstants.SUPER: 476 case TagConstants.LPAREN: 477 478 return true; 479 480 default: 481 return false; 482 } 483 } 484 485 /********************************************************************** 486 487 Parse a <TT>CastExpression</TT>. 488 489 <PRE> 490 CastExpression: 491 ( PrimitiveType Dimsopt ) UnaryExpression 492 ( Name Dimsopt ) UnaryExpressionNotPlusMinus 493 <PRE> 494 495 The non-terminal <TT>UnaryExpressionNotPlusMinus</TT> describes a 496 subset of <TT>UnaryExpression</TT> as described in chapter 19 of "The 497 Java Language Specification" 498 499 */ 500 501 502 //@ requires l != null && l.m_in != null; 503 //@ ensures \result != null; 504 public Expr parseCastExpression(Lex l) { 505 int locOpen = l.startingLoc; 506 expect( l, TagConstants.LPAREN ); 507 508 int parenCount = 1; 509 // count leading parens to handle ((A))a 510 while (l.ttype == TagConstants.LPAREN) { 511 parenCount++; 512 expect( l, TagConstants.LPAREN ); 513 } 514 515 Type castType = parseType(l); 516 int locClose = l.startingLoc; 517 518 // match all leading parens 519 while (parenCount > 0) { 520 expect( l, TagConstants.RPAREN ); 521 parenCount--; 522 } 523 524 Expr exprAfterCast = parseUnaryExpression(l); 525 return CastExpr.make( exprAfterCast, castType, locOpen, locClose ); 526 } 527 528 /********************************************************************** 529 530 Parse a <TT>PrimaryExpression</TT>. 531 532 <PRE> 533 PrimaryExpression: 534 PrimaryCore PrimarySuffix* 535 536 PrimaryCore: 537 Literal 538 Name 539 Name ArgumentList 540 this 541 super . Identifier 542 super . Identifier ArgumentList 543 NewExpression 544 LPAREN Expression RPAREN 545 TypeName . this [1.1] 546 Type . class [1.1] 547 (This allows void . class because we treat void as a primitive type) 548 549 PrimarySuffix: 550 ++ 551 -- 552 LSQBRACKET Expression RSQBRACKET 553 . Identifier 554 . Identifier ArgumentList 555 </PRE> 556 557 */ 558 559 //@ requires l != null && l.m_in != null; 560 //@ ensures \result != null; 561 protected Expr parsePrimaryExpression(Lex l) { 562 Expr primary; 563 564 /* hack to handle ((A))a as a typecast. 565 if (l.lookahead(0) == TagConstants.LPAREN && 566 l.lookahead(1) == TagConstants.LPAREN && 567 l.lookahead(2) == TagConstants.IDENT && 568 l.lookahead(3) == TagConstants.RPAREN && 569 l.lookahead(4) == TagConstants.RPAREN && 570 l.lookahead(5) == TagConstants.IDENT) { 571 return parseCastExpression2(l); 572 } */ 573 574 // First parse PrimaryCore into variable primary 575 switch( l.ttype ) { 576 577 // --- First try literals: Need to fix literal interface to Lex 578 579 case TagConstants.CHARLIT: 580 case TagConstants.DOUBLELIT: 581 case TagConstants.FLOATLIT: 582 case TagConstants.INTLIT: 583 case TagConstants.LONGLIT: 584 case TagConstants.STRINGLIT: 585 primary = LiteralExpr.make(l.ttype, l.auxVal, l.startingLoc); 586 l.getNextToken(); 587 break; 588 589 case TagConstants.TRUE: 590 primary = LiteralExpr.make( TagConstants.BOOLEANLIT, Boolean.TRUE, l.startingLoc ); 591 l.getNextToken(); 592 break; 593 594 case TagConstants.FALSE: 595 primary = LiteralExpr.make( TagConstants.BOOLEANLIT, Boolean.FALSE, l.startingLoc ); 596 l.getNextToken(); 597 break; 598 599 case TagConstants.NULL: 600 primary = LiteralExpr.make( TagConstants.NULLLIT, null, l.startingLoc ); 601 l.getNextToken(); 602 break; 603 604 // Get here => not a literal 605 606 // Try Name, Name ( ArgumentListopt ), Name []..., Name . class, 607 // Name . this 608 // 609 // Note that TypeModifierPragmas may appear between 610 // Name and (. 611 case TagConstants.ASSERT: 612 // Only process if assert is *not* a keyword. 613 if (Tool.options == null || Tool.options.assertIsKeyword) { 614 fail(l.startingLoc, "\"assert\" is a Java keyword when you use the" + 615 " -source 1.4 option; rename this identifier."); 616 } 617 // fall-through 618 case TagConstants.IDENT: 619 { 620 Name n = parseName(l); 621 TypeModifierPragmaVec tmodifiers = null; 622 /* 623 // Look for type modifiers on Name 624 if (l.ttype == TagConstants.TYPEMODIFIERPRAGMA) { 625 tmodifiers = parseTypeModifierPragmas(l); 626 } 627 */ 628 // May be followed by ( ArgumentListopt ) : 629 if (l.ttype == TagConstants.LPAREN) { 630 int locOpenParen = l.startingLoc; 631 ExprVec args = parseArgumentList(l); 632 primary = AmbiguousMethodInvocation.make(n, tmodifiers, 633 locOpenParen, args); 634 break; 635 } 636 637 // Look for 'TypeName . this' 638 if (l.lookahead(0) == TagConstants.FIELD && 639 l.lookahead(1) == TagConstants.THIS) { 640 expect( l, TagConstants.FIELD ); 641 int locThis = l.startingLoc; 642 expect( l, TagConstants.THIS ); 643 primary = ThisExpr.make(TypeName.make(n), locThis); 644 break; 645 } 646 647 // Or ([])* . class: 648 // (need to look ahead fully because of "<type>[] x;" declarations) 649 int i = 0; 650 while ( l.lookahead(i) == TagConstants.LSQBRACKET && 651 l.lookahead(i+1) == TagConstants.RSQBRACKET ) 652 i += 2; 653 if (l.lookahead(i) == TagConstants.FIELD && 654 l.lookahead(i+1) == TagConstants.CLASS) { 655 Type t = TypeName.make(n); 656 t = parseBracketPairs(l, t); 657 primary = parseClassLiteralSuffix(l, t); 658 break; 659 } 660 661 // Else, just an AmbiguousVariableAccess... 662 primary = AmbiguousVariableAccess.make( n ); 663 break; 664 } 665 666 case TagConstants.SUPER: 667 { 668 int locSuper = l.startingLoc; 669 Name n = parseSuper(l); 670 int locDot = l.startingLoc; 671 expect( l, TagConstants.FIELD ); 672 int locId = l.startingLoc; 673 Identifier id = parseIdentifier(l); 674 ObjectDesignator od = SuperObjectDesignator.make( locDot, locSuper ); 675 676 // super may be follows by type modifiers. 677 if( l.ttype == TagConstants.LPAREN || 678 l.ttype == TagConstants.TYPEMODIFIERPRAGMA) { 679 680 TypeModifierPragmaVec tmodifiers = null; 681 if (l.ttype == TagConstants.TYPEMODIFIERPRAGMA) { 682 tmodifiers = parseTypeModifierPragmas(l); 683 } 684 // is a super method invocation 685 // PrimaryCore ::= super . Identifier ( ArgumentListopt ) 686 int locOpenParen = l.startingLoc; 687 ExprVec args = parseArgumentList(l); 688 primary = MethodInvocation.make(od, id, tmodifiers, 689 locId, locOpenParen, args); 690 } else { 691 // is super field access 692 // PrimaryCore ::= super 693 primary = FieldAccess.make( od, id, locId ); 694 } 695 break; 696 } 697 698 case TagConstants.THIS: 699 primary = ThisExpr.make(null, l.startingLoc); 700 l.getNextToken(); 701 break; 702 703 case TagConstants.NEW: 704 primary = parseNewExpression(l); 705 break; 706 707 case TagConstants.LPAREN: 708 // LPAREN Expression RPAREN 709 int locOpenParen = l.startingLoc; 710 l.getNextToken(); 711 Expr e = parseExpression(l); 712 int locCloseParen = l.startingLoc; 713 expect( l, TagConstants.RPAREN ); 714 primary = ParenExpr.make( e, locOpenParen, locCloseParen ); 715 break; 716 717 default: 718 if (isPrimitiveKeywordTag(l.ttype)) { 719 Type t = parseType(l); 720 primary = parseClassLiteralSuffix(l, t); 721 } else { 722 fail(l.startingLoc, 723 "Unexpected token '" + PrettyPrint.inst.toString(l.ttype) + 724 "' in Primary expression"); 725 primary = null; // dummy initialization 726 } 727 } 728 729 // Ok, parsed a PrimaryCore expression into primary. 730 // Now handle PrimarySuffix* 731 732 return parsePrimarySuffix( l, primary ); 733 } 734 735 736 /** 737 * parses '. class', then produces a class literal expression using 738 * Type t. 739 */ 740 //@ requires l != null && t != null && l.m_in != null; 741 //@ requires t.syntax; 742 //@ ensures \result != null; 743 protected Expr parseClassLiteralSuffix(Lex l, Type t) { 744 int locDot = l.startingLoc; 745 expect( l, TagConstants.FIELD ); 746 expect( l, TagConstants.CLASS ); 747 748 return ClassLiteral.make(t, locDot); 749 } 750 751 752 //@ requires l != null && primary != null && l.m_in != null; 753 //@ ensures \result != null; 754 protected Expr parsePrimarySuffix(Lex l, Expr primary) { 755 756 for(;;) { 757 switch( l.ttype ) { 758 case TagConstants.INC: case TagConstants.DEC: 759 primary = UnaryExpr.make(l.ttype == TagConstants.INC 760 ? TagConstants.POSTFIXINC 761 : TagConstants.POSTFIXDEC, 762 primary, l.startingLoc ); 763 l.getNextToken(); 764 break; 765 766 case TagConstants.LSQBRACKET: { 767 if (l.lookahead(1) == TagConstants.RSQBRACKET 768 || l.lookahead(1) == TagConstants.STAR) 769 return primary; 770 int locOpenBracket = l.startingLoc; 771 l.getNextToken(); 772 Expr ndx = parseExpression(l); 773 primary = ArrayRefExpr.make(primary, ndx, 774 locOpenBracket, l.startingLoc); 775 expect( l, TagConstants.RSQBRACKET ); 776 break; 777 } 778 779 case TagConstants.FIELD: { 780 int locDot = l.startingLoc; 781 if( l.lookahead(1) == TagConstants.SUPER ) 782 return primary; 783 l.getNextToken(); 784 if( l.ttype == TagConstants.NEW ) { 785 int locNew = l.startingLoc; 786 Expr tmp = parseNewExpression(l); 787 if( tmp.getTag() != TagConstants.NEWINSTANCEEXPR) { 788 fail(locNew, "Cannot qualify an array allocation.\n"); 789 } 790 NewInstanceExpr result = (NewInstanceExpr)tmp; 791 result.enclosingInstance = primary; 792 result.locDot = locDot; 793 if( result.type.name.size() != 1 ) { 794 fail(result.type.getStartLoc(), 795 "Must have simple type name in a qualified new expression.\n"); 796 } 797 primary = result; 798 } else { 799 int locId = l.startingLoc; 800 ObjectDesignator od = ExprObjectDesignator.make( locDot, primary ); 801 if( l.ttype == TagConstants.CLASS ) 802 fail(l.startingLoc, ".class must follow a type"); 803 Identifier id = parseIdentifier(l); 804 // identifier may be followed by TypeModifierPragmas 805 if( l.ttype == TagConstants.LPAREN || 806 l.ttype == TagConstants.TYPEMODIFIERPRAGMA) { 807 TypeModifierPragmaVec tmodifiers = null; 808 if (l.ttype == TagConstants.TYPEMODIFIERPRAGMA) { 809 tmodifiers = parseTypeModifierPragmas(l); 810 } 811 // is method invocation 812 // PrimaryExpression . Identifier ( ArgumentListopt ) 813 int locOpenParen = l.startingLoc; 814 ExprVec args = parseArgumentList(l); 815 primary= MethodInvocation.make(od, id, tmodifiers, 816 locId, locOpenParen, args); 817 } else { 818 // is field access 819 // PrimaryExpression . Identifier 820 primary = FieldAccess.make( od, id, locId ); 821 } 822 } 823 break; 824 } 825 826 default: 827 // Have parsed Primary, and there is no valid PrimarySuffix 828 // So just return current primary 829 return primary; 830 } 831 } // End loop over PrimarySuffix 832 } 833 834 /** Parse a <TT>NewExpression</TT>. 835 NewExpression subsumes ClassInstanceCreationExpression and 836 ArrayCreationExpression. 837 838 <PRE> 839 NewExpression: 840 new TypeName ArgumentList [ TypeDeclBody ] 841 new PrimitiveTypeOrTypeName DimExpr+ BracketPairs* 842 843 DimExpr: 844 LSQBRACKET Expression RSQBRACKET 845 </PRE> 846 */ 847 848 //@ requires l != null && l.m_in != null; 849 //@ requires l.ttype == TagConstants.NEW; 850 //@ ensures \result != null; 851 public Expr parseNewExpression(Lex l) { 852 int locNew = l.startingLoc; 853 l.getNextToken(); 854 855 // Next is Name or PrimitiveType 856 Type type = parsePrimitiveTypeOrTypeName(l); 857 return parseNewExpressionTail(l,type,locNew); 858 } 859 public Expr parseNewExpressionTail(Lex l, Type type, int locNew) { 860 switch( l.ttype ) { 861 862 case TagConstants.LSQBRACKET: 863 int[] openBrackets = new int[4]; 864 int cOB = 0; 865 seqExpr.push(); 866 Type typeNew = null; // FIXME - JML needs this initializatio nbut Java does not 867 ExprVec dims; 868 ArrayInit init = null; // FIXME - JML needs this, javac does not 869 870 if (l.lookahead(1) != TagConstants.RSQBRACKET) { 871 // Parsing 'new' NonArrayType DimExprs Dims_opt 872 do { 873 // Should be LSQBRACKET Expression RSQBRACKET 874 if (cOB == openBrackets.length) { 875 int[] newOB = new int[2*cOB]; 876 System.arraycopy(openBrackets, 0, newOB, 0, cOB); 877 openBrackets = newOB; 878 } 879 openBrackets[cOB++] = l.startingLoc; 880 l.getNextToken(); 881 seqExpr.addElement( parseExpression(l) ); 882 expect( l, TagConstants.RSQBRACKET ); 883 } while(l.ttype == TagConstants.LSQBRACKET 884 && l.lookahead(1) != TagConstants.RSQBRACKET ); 885 typeNew = parseBracketPairs(l, type); 886 if (l.ttype == TagConstants.LSQBRACKET) { 887 fail(locNew, "Cannot index into a new array expression."); 888 } else if (l.ttype == TagConstants.LBRACE) { 889 fail(locNew, "Cannot provide both explicit dimensions and array initializer."); 890 } 891 init = null; 892 } else { 893 // Parsing 'new' NonArrayType Dims '{' ... '}' 894 openBrackets[cOB++] = l.startingLoc; 895 expect(l, TagConstants.LSQBRACKET); 896 expect(l, TagConstants.RSQBRACKET); 897 typeNew = parseBracketPairs(l, type); 898 if (l.ttype != TagConstants.LBRACE) { 899 fail(locNew, "Must provide either explicit dimensions or array initializer."); 900 } 901 init = parseArrayInitializer(l); 902 seqExpr.addElement(LiteralExpr.make(TagConstants.INTLIT, 903 new Integer(init.elems.size()), 904 init.locOpenBrace)); 905 } 906 dims = ExprVec.popFromStackVector(seqExpr); 907 Assert.notFalse(dims.size() == cOB); 908 return NewArrayExpr.make( typeNew, dims, init, locNew, openBrackets ); 909 910 case TagConstants.LPAREN: 911 // ClassInstanceCreationExpression 912 // type cannot be a PrimitiveType, must be TypeName 913 if( type instanceof TypeName ) { 914 int locOpenParen = l.startingLoc; 915 ExprVec args = parseArgumentList(l); 916 ClassDecl cd = null; 917 if( l.ttype == TagConstants.LBRACE ) { 918 int loc = l.startingLoc; 919 /* 920 * Warning: Parse.parseTypeDeclElemIntoSeq depends on 921 * anonymous classes id's starting with "$anon_"; if you 922 * update this code, make sure you change that routine in 923 * sync! 924 */ 925 Identifier id 926 = Identifier.intern("$anon_" + Location.toLineNumber(loc)); 927 928 expect( l, TagConstants.LBRACE ); 929 930 /* Build up Vec of TypeDeclElems in class or interface */ 931 seqTypeDeclElem.push(); 932 while( l.ttype != TagConstants.RBRACE ) 933 parseTypeDeclElemIntoSeqTDE( l, TagConstants.CLASS, id, false ); 934 TypeDeclElemVec elems 935 = TypeDeclElemVec.popFromStackVector( seqTypeDeclElem ); 936 // Note: Anonymous classes do not have default constructors! 937 938 int locCloseBrace = l.startingLoc; 939 expect( l, TagConstants.RBRACE ); 940 941 cd = ClassDecl.make(Modifiers.NONE, null, id, 942 TypeNameVec.make(), null, elems, 943 loc, loc, loc, locCloseBrace, 944 null); 945 } 946 return NewInstanceExpr.make( null, Location.NULL, 947 (TypeName)type, args, cd, 948 locNew, locOpenParen ); 949 } 950 // fall thru 951 952 default: 953 fail(l.startingLoc, "Bad 'new' expression"); 954 return null; // Dummy return 955 } 956 } 957 958 /** Parse an <TT>ArgumentList</TT>, which includes enclosing parens. 959 <PRE> 960 ArgumentList: 961 LPAREN [ Expression (, Expression)* ] RPAREN 962 </PRE> 963 */ 964 965 //@ requires l != null && l.m_in != null; 966 //@ ensures \result != null; 967 public ExprVec parseArgumentList(Lex l) { 968 expect( l, TagConstants.LPAREN ); 969 return parseExpressionList(l, TagConstants.RPAREN); 970 } 971 /* 972 if( l.ttype == TagConstants.RPAREN ) { 973 l.getNextToken(); 974 return ExprVec.make(); 975 } else { 976 seqExpr.push(); 977 for(;;) { 978 seqExpr.addElement( parseExpression(l) ); 979 if( l.ttype == TagConstants.RPAREN ) { 980 l.getNextToken(); 981 return ExprVec.popFromStackVector( seqExpr ); 982 } 983 expect( l, TagConstants.COMMA ); 984 } 985 } 986 } 987 */ 988 /** Parse an <TT>ExpressionList</TT>. Consumes specified terminator. 989 <PRE> 990 ExpressionList: 991 [ Expression (, Expression)* ] 992 </PRE> 993 */ 994 995 //@ requires l != null && l.m_in != null; 996 //@ ensures \result != null; 997 public ExprVec parseExpressionList(Lex l, int terminator) { 998 if( l.ttype == terminator ) { 999 l.getNextToken(); 1000 return ExprVec.make(); 1001 } else { 1002 seqExpr.push(); 1003 for(;;) { 1004 seqExpr.addElement( parseExpression(l) ); 1005 if( l.ttype == terminator ) { 1006 l.getNextToken(); 1007 return ExprVec.popFromStackVector( seqExpr ); 1008 } 1009 expect( l, TagConstants.COMMA ); 1010 } 1011 } 1012 } 1013 1014 /** Parse <TT>super</TT>. 1015 */ 1016 1017 //@ requires l != null && l.m_in != null; 1018 public Name parseSuper(Lex l) { 1019 expect( l, TagConstants.SUPER ); 1020 return SimpleName.make(Identifier.intern("super"), l.startingLoc); 1021 } 1022 1023 /** Parse VariableInitializer. 1024 <PRE> 1025 VariableInitializer: 1026 Expression 1027 ArrayInitializer 1028 1029 ArrayInitializer: 1030 { [ VariableInitializer ( , VariableInitializer )*] ,opt } 1031 </PRE> 1032 */ 1033 1034 //@ requires l != null && l.m_in != null; 1035 //@ ensures \result != null; 1036 public VarInit parseVariableInitializer(Lex l, boolean specOnly) { 1037 if( l.ttype == TagConstants.LBRACE ) { 1038 return parseArrayInitializer(l); 1039 } else { 1040 // Just a regular expression 1041 return parseExpression(l); 1042 } 1043 } 1044 1045 //@ requires l.ttype == TagConstants.LBRACE; 1046 //@ requires l != null && l.m_in != null; 1047 //@ ensures \result != null; 1048 public ArrayInit parseArrayInitializer(Lex l) { 1049 int locOpenBrace = l.startingLoc; 1050 expect( l, TagConstants.LBRACE ); 1051 seqVarInit.push(); 1052 1053 if( l.ttype == TagConstants.COMMA ) { 1054 // Should be LBRACE COMMA RBRACE 1055 l.getNextToken(); 1056 } else { 1057 while( l.ttype != TagConstants.RBRACE ) { 1058 1059 seqVarInit.addElement( parseVariableInitializer(l, false) ); 1060 1061 switch( l.ttype ) { 1062 case TagConstants.COMMA: 1063 l.getNextToken(); break; 1064 case TagConstants.RBRACE: 1065 break; 1066 default: 1067 fail(l.startingLoc, "Bad variable initializer"); 1068 } 1069 } 1070 } 1071 int locCloseBrace = l.startingLoc; 1072 if( l.ttype != TagConstants.RBRACE ) 1073 fail(l.startingLoc, "Bad variable initializer"); 1074 l.getNextToken(); 1075 1076 return ArrayInit.make( VarInitVec.popFromStackVector( seqVarInit ), 1077 locOpenBrace, locCloseBrace ); 1078 } 1079 1080 // ---------------------------------------------------------------------- 1081 1082 public ParseExpr() { 1083 //@ set seqExpr.elementType = \type(Expr); 1084 //@ set seqExpr.owner = this; 1085 1086 //@ set seqVarInit.elementType = \type(VarInit); 1087 //@ set seqVarInit.owner = this; 1088 1089 //@ set seqTypeDeclElem.elementType = \type(TypeDeclElem); 1090 //@ set seqTypeDeclElem.owner = this; 1091 1092 // initialize the operator precedence table 1093 1094 addOperator( TagConstants.STAR, 170, true ); 1095 addOperator( TagConstants.DIV, 170, true ); 1096 addOperator( TagConstants.MOD, 170, true ); 1097 1098 addOperator( TagConstants.ADD, 160, true ); 1099 addOperator( TagConstants.SUB, 160, true ); 1100 1101 addOperator( TagConstants.LSHIFT, 150, true ); 1102 addOperator( TagConstants.RSHIFT, 150, true ); 1103 addOperator( TagConstants.URSHIFT, 150, true ); 1104 1105 addOperator( TagConstants.GE, 140, true ); 1106 addOperator( TagConstants.GT, 140, true ); 1107 addOperator( TagConstants.LT, 140, true ); 1108 addOperator( TagConstants.LE, 140, true ); 1109 1110 // handled specially: 1111 addOperator( TagConstants.INSTANCEOF, 140, true ); 1112 1113 1114 addOperator( TagConstants.EQ, 130, true ); 1115 addOperator( TagConstants.NE, 130, true ); 1116 1117 addOperator( TagConstants.BITAND, 120, true ); 1118 1119 addOperator( TagConstants.BITXOR, 110, true ); 1120 1121 addOperator( TagConstants.BITOR, 100, true ); 1122 1123 addOperator( TagConstants.AND, 90, true ); 1124 1125 addOperator( TagConstants.OR, 80, true ); 1126 1127 addOperator( TagConstants.QUESTIONMARK, 70, true ); 1128 1129 addOperator( TagConstants.ASSIGN, 60, false ); 1130 addOperator( TagConstants.ASGMUL, 60, false ); 1131 addOperator( TagConstants.ASGDIV, 60, false ); 1132 addOperator( TagConstants.ASGREM, 60, false ); 1133 addOperator( TagConstants.ASGADD, 60, false ); 1134 addOperator( TagConstants.ASGSUB, 60, false ); 1135 addOperator( TagConstants.ASGLSHIFT, 60, false ); 1136 addOperator( TagConstants.ASGRSHIFT, 60, false ); 1137 addOperator( TagConstants.ASGURSHIFT, 60, false ); 1138 addOperator( TagConstants.ASGBITAND, 60, false ); 1139 addOperator( TagConstants.ASGBITOR, 60, false ); 1140 addOperator( TagConstants.ASGBITXOR, 60, false ); 1141 } 1142 1143 1144 /** 1145 * Internal working storage for parseNewExpression, 1146 * parseExpressionList, and ParseStmt.parseForStmt functions. 1147 */ 1148 //@ invariant seqExpr.elementType == \type(Expr); 1149 //@ invariant seqExpr.owner == this; 1150 protected final /*@ non_null @*/ StackVector seqExpr 1151 = new StackVector(); 1152 1153 /** 1154 * Internal working storage for parseArrayInitializer function. 1155 */ 1156 //@ invariant seqVarInit.elementType == \type(VarInit); 1157 //@ invariant seqVarInit.owner == this; 1158 protected final /*@ non_null @*/ StackVector seqVarInit 1159 = new StackVector(); 1160 1161 /** 1162 * Internal working storage for parseNewExpression function. 1163 */ 1164 //@ invariant seqTypeDeclElem.elementType == \type(TypeDeclElem); 1165 //@ invariant seqTypeDeclElem.owner == this; 1166 protected final /*@ non_null @*/ StackVector seqTypeDeclElem 1167 = new StackVector(); 1168 }