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    }