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    }