    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    }