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