src/share/classes/com/sun/tools/javac/parser/JavacParser.java

Print this page




  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.parser;
  27 
  28 import java.util.*;
  29 
  30 import com.sun.tools.javac.code.*;
  31 import com.sun.tools.javac.parser.Tokens.*;
  32 import com.sun.tools.javac.tree.*;
  33 import com.sun.tools.javac.tree.JCTree.*;
  34 import com.sun.tools.javac.util.*;
  35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  37 import com.sun.tools.javac.util.List;
  38 
  39 import static com.sun.tools.javac.util.ListBuffer.lb;
  40 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;








  41 
  42 /** The parser maps a token sequence into an abstract syntax
  43  *  tree. It operates by recursive descent, with code derived
  44  *  systematically from an LL(1) grammar. For efficiency reasons, an
  45  *  operator precedence scheme is used for parsing binary operation
  46  *  expressions.
  47  *
  48  *  <p><b>This is NOT part of any supported API.
  49  *  If you write code that depends on this, you do so at your own risk.
  50  *  This code and its internal interfaces are subject to change or
  51  *  deletion without notice.</b>
  52  */
  53 public class JavacParser implements Parser {
  54 
  55     /** The number of precedence levels of infix operators.
  56      */
  57     private static final int infixPrecedenceLevels = 10;
  58 
  59     /** The scanner used for lexical analysis.
  60      */


 740         int top = 0;
 741         odStack[0] = t;
 742         int startPos = token.pos;
 743         Token topOp = Tokens.DUMMY;
 744         while (prec(token.kind) >= minprec) {
 745             opStack[top] = topOp;
 746             top++;
 747             topOp = token;
 748             nextToken();
 749             odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3();
 750             while (top > 0 && prec(topOp.kind) >= prec(token.kind)) {
 751                 odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1],
 752                                         odStack[top]);
 753                 top--;
 754                 topOp = opStack[top];
 755             }
 756         }
 757         Assert.check(top == 0);
 758         t = odStack[0];
 759 
 760         if (t.getTag() == JCTree.PLUS) {
 761             StringBuffer buf = foldStrings(t);
 762             if (buf != null) {
 763                 t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString()));
 764             }
 765         }
 766 
 767         odStackSupply.elems = savedOd; // optimization
 768         opStackSupply.elems = savedOp; // optimization
 769         return t;
 770     }
 771 //where
 772         /** Construct a binary or type test node.
 773          */
 774         private JCExpression makeOp(int pos,
 775                                     TokenKind topOp,
 776                                     JCExpression od1,
 777                                     JCExpression od2)
 778         {
 779             if (topOp == INSTANCEOF) {
 780                 return F.at(pos).TypeTest(od1, od2);
 781             } else {
 782                 return F.at(pos).Binary(optag(topOp), od1, od2);
 783             }
 784         }
 785         /** If tree is a concatenation of string literals, replace it
 786          *  by a single literal representing the concatenated string.
 787          */
 788         protected StringBuffer foldStrings(JCTree tree) {
 789             if (!allowStringFolding)
 790                 return null;
 791             List<String> buf = List.nil();
 792             while (true) {
 793                 if (tree.getTag() == JCTree.LITERAL) {
 794                     JCLiteral lit = (JCLiteral) tree;
 795                     if (lit.typetag == TypeTags.CLASS) {
 796                         StringBuffer sbuf =
 797                             new StringBuffer((String)lit.value);
 798                         while (buf.nonEmpty()) {
 799                             sbuf.append(buf.head);
 800                             buf = buf.tail;
 801                         }
 802                         return sbuf;
 803                     }
 804                 } else if (tree.getTag() == JCTree.PLUS) {
 805                     JCBinary op = (JCBinary)tree;
 806                     if (op.rhs.getTag() == JCTree.LITERAL) {
 807                         JCLiteral lit = (JCLiteral) op.rhs;
 808                         if (lit.typetag == TypeTags.CLASS) {
 809                             buf = buf.prepend((String) lit.value);
 810                             tree = op.lhs;
 811                             continue;
 812                         }
 813                     }
 814                 }
 815                 return null;
 816             }
 817         }
 818 
 819         /** optimization: To save allocating a new operand/operator stack
 820          *  for every binary operation, we use supplys.
 821          */
 822         ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
 823         ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
 824 
 825         private JCExpression[] newOdStack() {
 826             if (odStackSupply.elems == odStackSupply.last)


 882                 nextToken();
 883                 mode = EXPR;
 884                 if (tk == SUB &&
 885                     (token.kind == INTLITERAL || token.kind == LONGLITERAL) &&
 886                     token.radix() == 10) {
 887                     mode = EXPR;
 888                     t = literal(names.hyphen, pos);
 889                 } else {
 890                     t = term3();
 891                     return F.at(pos).Unary(unoptag(tk), t);
 892                 }
 893             } else return illegal();
 894             break;
 895         case LPAREN:
 896             if (typeArgs == null && (mode & EXPR) != 0) {
 897                 nextToken();
 898                 mode = EXPR | TYPE | NOPARAMS;
 899                 t = term3();
 900                 if ((mode & TYPE) != 0 && token.kind == LT) {
 901                     // Could be a cast to a parameterized type
 902                     int op = JCTree.LT;
 903                     int pos1 = token.pos;
 904                     nextToken();
 905                     mode &= (EXPR | TYPE);
 906                     mode |= TYPEARG;
 907                     JCExpression t1 = term3();
 908                     if ((mode & TYPE) != 0 &&
 909                         (token.kind == COMMA || token.kind == GT)) {
 910                         mode = TYPE;
 911                         ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
 912                         args.append(t1);
 913                         while (token.kind == COMMA) {
 914                             nextToken();
 915                             args.append(typeArgument());
 916                         }
 917                         accept(GT);
 918                         t = toP(F.at(pos1).TypeApply(t, args.toList()));
 919                         checkGenerics();
 920                         while (token.kind == DOT) {
 921                             nextToken();
 922                             mode = TYPE;


1136                 } else if (token.kind == NEW && (mode & EXPR) != 0) {
1137                     if (typeArgs != null) return illegal();
1138                     mode = EXPR;
1139                     int pos2 = token.pos;
1140                     nextToken();
1141                     if (token.kind == LT) typeArgs = typeArguments(false);
1142                     t = innerCreator(pos2, typeArgs, t);
1143                     typeArgs = null;
1144                 } else {
1145                     t = toP(F.at(pos1).Select(t, ident()));
1146                     t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1147                     typeArgs = null;
1148                 }
1149             } else {
1150                 break;
1151             }
1152         }
1153         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1154             mode = EXPR;
1155             t = to(F.at(token.pos).Unary(
1156                   token.kind == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
1157             nextToken();
1158         }
1159         return toP(t);
1160     }
1161 
1162     /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1163      */
1164     JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1165         nextToken();
1166         if (token.kind == LPAREN || typeArgs != null) {
1167             t = arguments(typeArgs, t);
1168         } else {
1169             int pos = token.pos;
1170             accept(DOT);
1171             typeArgs = (token.kind == LT) ? typeArguments(false) : null;
1172             t = toP(F.at(pos).Select(t, ident()));
1173             t = argumentsOpt(typeArgs, t);
1174         }
1175         return t;
1176     }


1609             case INTERFACE:
1610             case CLASS:
1611                 String dc = token.docComment;
1612                 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
1613                 break;
1614             case ENUM:
1615             case ASSERT:
1616                 if (allowEnums && token.kind == ENUM) {
1617                     error(token.pos, "local.enum");
1618                     dc = token.docComment;
1619                     stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
1620                     break;
1621                 } else if (allowAsserts && token.kind == ASSERT) {
1622                     stats.append(parseStatement());
1623                     break;
1624                 }
1625                 /* fall through to default */
1626             default:
1627                 Token prevToken = token;
1628                 JCExpression t = term(EXPR | TYPE);
1629                 if (token.kind == COLON && t.getTag() == JCTree.IDENT) {
1630                     nextToken();
1631                     JCStatement stat = parseStatement();
1632                     stats.append(F.at(pos).Labelled(prevToken.name(), stat));
1633                 } else if ((lastmode & TYPE) != 0 &&
1634                            (token.kind == IDENTIFIER ||
1635                             token.kind == ASSERT ||
1636                             token.kind == ENUM)) {
1637                     pos = token.pos;
1638                     JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1639                     F.at(pos);
1640                     stats.appendList(variableDeclarators(mods, t,
1641                                                          new ListBuffer<JCStatement>()));
1642                     // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1643                     storeEnd(stats.elems.last(), token.endPos);
1644                     accept(SEMI);
1645                 } else {
1646                     // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1647                     stats.append(to(F.at(pos).Exec(checkExprStat(t))));
1648                     accept(SEMI);
1649                 }


1684         int pos = token.pos;
1685         switch (token.kind) {
1686         case LBRACE:
1687             return block();
1688         case IF: {
1689             nextToken();
1690             JCExpression cond = parExpression();
1691             JCStatement thenpart = parseStatement();
1692             JCStatement elsepart = null;
1693             if (token.kind == ELSE) {
1694                 nextToken();
1695                 elsepart = parseStatement();
1696             }
1697             return F.at(pos).If(cond, thenpart, elsepart);
1698         }
1699         case FOR: {
1700             nextToken();
1701             accept(LPAREN);
1702             List<JCStatement> inits = token.kind == SEMI ? List.<JCStatement>nil() : forInit();
1703             if (inits.length() == 1 &&
1704                 inits.head.getTag() == JCTree.VARDEF &&
1705                 ((JCVariableDecl) inits.head).init == null &&
1706                 token.kind == COLON) {
1707                 checkForeach();
1708                 JCVariableDecl var = (JCVariableDecl)inits.head;
1709                 accept(COLON);
1710                 JCExpression expr = parseExpression();
1711                 accept(RPAREN);
1712                 JCStatement body = parseStatement();
1713                 return F.at(pos).ForeachLoop(var, expr, body);
1714             } else {
1715                 accept(SEMI);
1716                 JCExpression cond = token.kind == SEMI ? null : parseExpression();
1717                 accept(SEMI);
1718                 List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
1719                 accept(RPAREN);
1720                 JCStatement body = parseStatement();
1721                 return F.at(pos).ForLoop(inits, cond, steps, body);
1722             }
1723         }
1724         case WHILE: {


1817             return toP(F.Exec(syntaxError("catch.without.try")));
1818         case ASSERT: {
1819             if (allowAsserts && token.kind == ASSERT) {
1820                 nextToken();
1821                 JCExpression assertion = parseExpression();
1822                 JCExpression message = null;
1823                 if (token.kind == COLON) {
1824                     nextToken();
1825                     message = parseExpression();
1826                 }
1827                 JCAssert t = to(F.at(pos).Assert(assertion, message));
1828                 accept(SEMI);
1829                 return t;
1830             }
1831             /* else fall through to default case */
1832         }
1833         case ENUM:
1834         default:
1835             Token prevToken = token;
1836             JCExpression expr = parseExpression();
1837             if (token.kind == COLON && expr.getTag() == JCTree.IDENT) {
1838                 nextToken();
1839                 JCStatement stat = parseStatement();
1840                 return F.at(pos).Labelled(prevToken.name(), stat);
1841             } else {
1842                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1843                 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
1844                 accept(SEMI);
1845                 return stat;
1846             }
1847         }
1848     }
1849 
1850     /** CatchClause     = CATCH "(" FormalParameter ")" Block
1851      */
1852     protected JCCatch catchClause() {
1853         int pos = token.pos;
1854         accept(CATCH);
1855         accept(LPAREN);
1856         JCModifiers mods = optFinal(Flags.PARAMETER);
1857         List<JCExpression> catchTypes = catchTypes();


2070         accept(LPAREN);
2071         ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2072         if (token.kind != RPAREN) {
2073             buf.append(annotationFieldValue());
2074             while (token.kind == COMMA) {
2075                 nextToken();
2076                 buf.append(annotationFieldValue());
2077             }
2078         }
2079         accept(RPAREN);
2080         return buf.toList();
2081     }
2082 
2083     /** AnnotationFieldValue    = AnnotationValue
2084      *                          | Identifier "=" AnnotationValue
2085      */
2086     JCExpression annotationFieldValue() {
2087         if (token.kind == IDENTIFIER) {
2088             mode = EXPR;
2089             JCExpression t1 = term1();
2090             if (t1.getTag() == JCTree.IDENT && token.kind == EQ) {
2091                 int pos = token.pos;
2092                 accept(EQ);
2093                 JCExpression v = annotationValue();
2094                 return toP(F.at(pos).Assign(t1, v));
2095             } else {
2096                 return t1;
2097             }
2098         }
2099         return annotationValue();
2100     }
2101 
2102     /* AnnotationValue          = ConditionalExpression
2103      *                          | Annotation
2104      *                          | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
2105      */
2106     JCExpression annotationValue() {
2107         int pos;
2108         switch (token.kind) {
2109         case MONKEYS_AT:
2110             pos = token.pos;


2600                 return List.<JCTree>of(block(pos, mods.flags));
2601             } else {
2602                 pos = token.pos;
2603                 List<JCTypeParameter> typarams = typeParametersOpt();
2604                 // if there are type parameters but no modifiers, save the start
2605                 // position of the method in the modifiers.
2606                 if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
2607                     mods.pos = pos;
2608                     storeEnd(mods, pos);
2609                 }
2610                 Token tk = token;
2611                 pos = token.pos;
2612                 JCExpression type;
2613                 boolean isVoid = token.kind == VOID;
2614                 if (isVoid) {
2615                     type = to(F.at(pos).TypeIdent(TypeTags.VOID));
2616                     nextToken();
2617                 } else {
2618                     type = parseType();
2619                 }
2620                 if (token.kind == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
2621                     if (isInterface || tk.name() != className)
2622                         error(pos, "invalid.meth.decl.ret.type.req");
2623                     return List.of(methodDeclaratorRest(
2624                         pos, mods, null, names.init, typarams,
2625                         isInterface, true, dc));
2626                 } else {
2627                     pos = token.pos;
2628                     Name name = ident();
2629                     if (token.kind == LPAREN) {
2630                         return List.of(methodDeclaratorRest(
2631                             pos, mods, type, name, typarams,
2632                             isInterface, isVoid, dc));
2633                     } else if (!isVoid && typarams.isEmpty()) {
2634                         List<JCTree> defs =
2635                             variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
2636                                                     new ListBuffer<JCTree>()).toList();
2637                         storeEnd(defs.last(), token.endPos);
2638                         accept(SEMI);
2639                         return defs;
2640                     } else {


2797     }
2798 
2799 /* ---------- auxiliary methods -------------- */
2800 
2801     void error(int pos, String key, Object ... args) {
2802         log.error(DiagnosticFlag.SYNTAX, pos, key, args);
2803     }
2804 
2805     void error(DiagnosticPosition pos, String key, Object ... args) {
2806         log.error(DiagnosticFlag.SYNTAX, pos, key, args);
2807     }
2808 
2809     void warning(int pos, String key, Object ... args) {
2810         log.warning(pos, key, args);
2811     }
2812 
2813     /** Check that given tree is a legal expression statement.
2814      */
2815     protected JCExpression checkExprStat(JCExpression t) {
2816         switch(t.getTag()) {
2817         case JCTree.PREINC: case JCTree.PREDEC:
2818         case JCTree.POSTINC: case JCTree.POSTDEC:
2819         case JCTree.ASSIGN:
2820         case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG:
2821         case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG:
2822         case JCTree.PLUS_ASG: case JCTree.MINUS_ASG:
2823         case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG:
2824         case JCTree.APPLY: case JCTree.NEWCLASS:
2825         case JCTree.ERRONEOUS:
2826             return t;
2827         default:
2828             JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
2829             error(ret, "not.stmt");
2830             return ret;
2831         }
2832     }
2833 
2834     /** Return precedence of operator represented by token,
2835      *  -1 if token is not a binary operator. @see TreeInfo.opPrec
2836      */
2837     static int prec(TokenKind token) {
2838         int oc = optag(token);
2839         return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
2840     }
2841 
2842     /**
2843      * Return the lesser of two positions, making allowance for either one
2844      * being unset.
2845      */
2846     static int earlier(int pos1, int pos2) {
2847         if (pos1 == Position.NOPOS)
2848             return pos2;
2849         if (pos2 == Position.NOPOS)
2850             return pos1;
2851         return (pos1 < pos2 ? pos1 : pos2);
2852     }
2853 
2854     /** Return operation tag of binary operator represented by token,
2855      *  -1 if token is not a binary operator.
2856      */
2857     static int optag(TokenKind token) {
2858         switch (token) {
2859         case BARBAR:
2860             return JCTree.OR;
2861         case AMPAMP:
2862             return JCTree.AND;
2863         case BAR:
2864             return JCTree.BITOR;
2865         case BAREQ:
2866             return JCTree.BITOR_ASG;
2867         case CARET:
2868             return JCTree.BITXOR;
2869         case CARETEQ:
2870             return JCTree.BITXOR_ASG;
2871         case AMP:
2872             return JCTree.BITAND;
2873         case AMPEQ:
2874             return JCTree.BITAND_ASG;
2875         case EQEQ:
2876             return JCTree.EQ;
2877         case BANGEQ:
2878             return JCTree.NE;
2879         case LT:
2880             return JCTree.LT;
2881         case GT:
2882             return JCTree.GT;
2883         case LTEQ:
2884             return JCTree.LE;
2885         case GTEQ:
2886             return JCTree.GE;
2887         case LTLT:
2888             return JCTree.SL;
2889         case LTLTEQ:
2890             return JCTree.SL_ASG;
2891         case GTGT:
2892             return JCTree.SR;
2893         case GTGTEQ:
2894             return JCTree.SR_ASG;
2895         case GTGTGT:
2896             return JCTree.USR;
2897         case GTGTGTEQ:
2898             return JCTree.USR_ASG;
2899         case PLUS:
2900             return JCTree.PLUS;
2901         case PLUSEQ:
2902             return JCTree.PLUS_ASG;
2903         case SUB:
2904             return JCTree.MINUS;
2905         case SUBEQ:
2906             return JCTree.MINUS_ASG;
2907         case STAR:
2908             return JCTree.MUL;
2909         case STAREQ:
2910             return JCTree.MUL_ASG;
2911         case SLASH:
2912             return JCTree.DIV;
2913         case SLASHEQ:
2914             return JCTree.DIV_ASG;
2915         case PERCENT:
2916             return JCTree.MOD;
2917         case PERCENTEQ:
2918             return JCTree.MOD_ASG;
2919         case INSTANCEOF:
2920             return JCTree.TYPETEST;
2921         default:
2922             return -1;
2923         }
2924     }
2925 
2926     /** Return operation tag of unary operator represented by token,
2927      *  -1 if token is not a binary operator.
2928      */
2929     static int unoptag(TokenKind token) {
2930         switch (token) {
2931         case PLUS:
2932             return JCTree.POS;
2933         case SUB:
2934             return JCTree.NEG;
2935         case BANG:
2936             return JCTree.NOT;
2937         case TILDE:
2938             return JCTree.COMPL;
2939         case PLUSPLUS:
2940             return JCTree.PREINC;
2941         case SUBSUB:
2942             return JCTree.PREDEC;
2943         default:
2944             return -1;
2945         }
2946     }
2947 
2948     /** Return type tag of basic type represented by token,
2949      *  -1 if token is not a basic type identifier.
2950      */
2951     static int typetag(TokenKind token) {
2952         switch (token) {
2953         case BYTE:
2954             return TypeTags.BYTE;
2955         case CHAR:
2956             return TypeTags.CHAR;
2957         case SHORT:
2958             return TypeTags.SHORT;
2959         case INT:
2960             return TypeTags.INT;
2961         case LONG:
2962             return TypeTags.LONG;
2963         case FLOAT:
2964             return TypeTags.FLOAT;




  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.parser;
  27 
  28 import java.util.*;
  29 
  30 import com.sun.tools.javac.code.*;
  31 import com.sun.tools.javac.parser.Tokens.*;
  32 import com.sun.tools.javac.tree.*;
  33 import com.sun.tools.javac.tree.JCTree.*;
  34 import com.sun.tools.javac.util.*;
  35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  37 import com.sun.tools.javac.util.List;
  38 
  39 import static com.sun.tools.javac.util.ListBuffer.lb;
  40 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
  41 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
  42 import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ;
  43 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
  44 import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
  45 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE;
  46 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH;
  47 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
  48 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  49 
  50 /** The parser maps a token sequence into an abstract syntax
  51  *  tree. It operates by recursive descent, with code derived
  52  *  systematically from an LL(1) grammar. For efficiency reasons, an
  53  *  operator precedence scheme is used for parsing binary operation
  54  *  expressions.
  55  *
  56  *  <p><b>This is NOT part of any supported API.
  57  *  If you write code that depends on this, you do so at your own risk.
  58  *  This code and its internal interfaces are subject to change or
  59  *  deletion without notice.</b>
  60  */
  61 public class JavacParser implements Parser {
  62 
  63     /** The number of precedence levels of infix operators.
  64      */
  65     private static final int infixPrecedenceLevels = 10;
  66 
  67     /** The scanner used for lexical analysis.
  68      */


 748         int top = 0;
 749         odStack[0] = t;
 750         int startPos = token.pos;
 751         Token topOp = Tokens.DUMMY;
 752         while (prec(token.kind) >= minprec) {
 753             opStack[top] = topOp;
 754             top++;
 755             topOp = token;
 756             nextToken();
 757             odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3();
 758             while (top > 0 && prec(topOp.kind) >= prec(token.kind)) {
 759                 odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1],
 760                                         odStack[top]);
 761                 top--;
 762                 topOp = opStack[top];
 763             }
 764         }
 765         Assert.check(top == 0);
 766         t = odStack[0];
 767 
 768         if (t.hasTag(JCTree.Tag.PLUS)) {
 769             StringBuffer buf = foldStrings(t);
 770             if (buf != null) {
 771                 t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString()));
 772             }
 773         }
 774 
 775         odStackSupply.elems = savedOd; // optimization
 776         opStackSupply.elems = savedOp; // optimization
 777         return t;
 778     }
 779 //where
 780         /** Construct a binary or type test node.
 781          */
 782         private JCExpression makeOp(int pos,
 783                                     TokenKind topOp,
 784                                     JCExpression od1,
 785                                     JCExpression od2)
 786         {
 787             if (topOp == INSTANCEOF) {
 788                 return F.at(pos).TypeTest(od1, od2);
 789             } else {
 790                 return F.at(pos).Binary(optag(topOp), od1, od2);
 791             }
 792         }
 793         /** If tree is a concatenation of string literals, replace it
 794          *  by a single literal representing the concatenated string.
 795          */
 796         protected StringBuffer foldStrings(JCTree tree) {
 797             if (!allowStringFolding)
 798                 return null;
 799             List<String> buf = List.nil();
 800             while (true) {
 801                 if (tree.hasTag(LITERAL)) {
 802                     JCLiteral lit = (JCLiteral) tree;
 803                     if (lit.typetag == TypeTags.CLASS) {
 804                         StringBuffer sbuf =
 805                             new StringBuffer((String)lit.value);
 806                         while (buf.nonEmpty()) {
 807                             sbuf.append(buf.head);
 808                             buf = buf.tail;
 809                         }
 810                         return sbuf;
 811                     }
 812                 } else if (tree.hasTag(JCTree.Tag.PLUS)) {
 813                     JCBinary op = (JCBinary)tree;
 814                     if (op.rhs.hasTag(LITERAL)) {
 815                         JCLiteral lit = (JCLiteral) op.rhs;
 816                         if (lit.typetag == TypeTags.CLASS) {
 817                             buf = buf.prepend((String) lit.value);
 818                             tree = op.lhs;
 819                             continue;
 820                         }
 821                     }
 822                 }
 823                 return null;
 824             }
 825         }
 826 
 827         /** optimization: To save allocating a new operand/operator stack
 828          *  for every binary operation, we use supplys.
 829          */
 830         ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
 831         ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
 832 
 833         private JCExpression[] newOdStack() {
 834             if (odStackSupply.elems == odStackSupply.last)


 890                 nextToken();
 891                 mode = EXPR;
 892                 if (tk == SUB &&
 893                     (token.kind == INTLITERAL || token.kind == LONGLITERAL) &&
 894                     token.radix() == 10) {
 895                     mode = EXPR;
 896                     t = literal(names.hyphen, pos);
 897                 } else {
 898                     t = term3();
 899                     return F.at(pos).Unary(unoptag(tk), t);
 900                 }
 901             } else return illegal();
 902             break;
 903         case LPAREN:
 904             if (typeArgs == null && (mode & EXPR) != 0) {
 905                 nextToken();
 906                 mode = EXPR | TYPE | NOPARAMS;
 907                 t = term3();
 908                 if ((mode & TYPE) != 0 && token.kind == LT) {
 909                     // Could be a cast to a parameterized type
 910                     JCTree.Tag op = JCTree.Tag.LT;
 911                     int pos1 = token.pos;
 912                     nextToken();
 913                     mode &= (EXPR | TYPE);
 914                     mode |= TYPEARG;
 915                     JCExpression t1 = term3();
 916                     if ((mode & TYPE) != 0 &&
 917                         (token.kind == COMMA || token.kind == GT)) {
 918                         mode = TYPE;
 919                         ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
 920                         args.append(t1);
 921                         while (token.kind == COMMA) {
 922                             nextToken();
 923                             args.append(typeArgument());
 924                         }
 925                         accept(GT);
 926                         t = toP(F.at(pos1).TypeApply(t, args.toList()));
 927                         checkGenerics();
 928                         while (token.kind == DOT) {
 929                             nextToken();
 930                             mode = TYPE;


1144                 } else if (token.kind == NEW && (mode & EXPR) != 0) {
1145                     if (typeArgs != null) return illegal();
1146                     mode = EXPR;
1147                     int pos2 = token.pos;
1148                     nextToken();
1149                     if (token.kind == LT) typeArgs = typeArguments(false);
1150                     t = innerCreator(pos2, typeArgs, t);
1151                     typeArgs = null;
1152                 } else {
1153                     t = toP(F.at(pos1).Select(t, ident()));
1154                     t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1155                     typeArgs = null;
1156                 }
1157             } else {
1158                 break;
1159             }
1160         }
1161         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1162             mode = EXPR;
1163             t = to(F.at(token.pos).Unary(
1164                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1165             nextToken();
1166         }
1167         return toP(t);
1168     }
1169 
1170     /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1171      */
1172     JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1173         nextToken();
1174         if (token.kind == LPAREN || typeArgs != null) {
1175             t = arguments(typeArgs, t);
1176         } else {
1177             int pos = token.pos;
1178             accept(DOT);
1179             typeArgs = (token.kind == LT) ? typeArguments(false) : null;
1180             t = toP(F.at(pos).Select(t, ident()));
1181             t = argumentsOpt(typeArgs, t);
1182         }
1183         return t;
1184     }


1617             case INTERFACE:
1618             case CLASS:
1619                 String dc = token.docComment;
1620                 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
1621                 break;
1622             case ENUM:
1623             case ASSERT:
1624                 if (allowEnums && token.kind == ENUM) {
1625                     error(token.pos, "local.enum");
1626                     dc = token.docComment;
1627                     stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
1628                     break;
1629                 } else if (allowAsserts && token.kind == ASSERT) {
1630                     stats.append(parseStatement());
1631                     break;
1632                 }
1633                 /* fall through to default */
1634             default:
1635                 Token prevToken = token;
1636                 JCExpression t = term(EXPR | TYPE);
1637                 if (token.kind == COLON && t.hasTag(IDENT)) {
1638                     nextToken();
1639                     JCStatement stat = parseStatement();
1640                     stats.append(F.at(pos).Labelled(prevToken.name(), stat));
1641                 } else if ((lastmode & TYPE) != 0 &&
1642                            (token.kind == IDENTIFIER ||
1643                             token.kind == ASSERT ||
1644                             token.kind == ENUM)) {
1645                     pos = token.pos;
1646                     JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1647                     F.at(pos);
1648                     stats.appendList(variableDeclarators(mods, t,
1649                                                          new ListBuffer<JCStatement>()));
1650                     // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1651                     storeEnd(stats.elems.last(), token.endPos);
1652                     accept(SEMI);
1653                 } else {
1654                     // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1655                     stats.append(to(F.at(pos).Exec(checkExprStat(t))));
1656                     accept(SEMI);
1657                 }


1692         int pos = token.pos;
1693         switch (token.kind) {
1694         case LBRACE:
1695             return block();
1696         case IF: {
1697             nextToken();
1698             JCExpression cond = parExpression();
1699             JCStatement thenpart = parseStatement();
1700             JCStatement elsepart = null;
1701             if (token.kind == ELSE) {
1702                 nextToken();
1703                 elsepart = parseStatement();
1704             }
1705             return F.at(pos).If(cond, thenpart, elsepart);
1706         }
1707         case FOR: {
1708             nextToken();
1709             accept(LPAREN);
1710             List<JCStatement> inits = token.kind == SEMI ? List.<JCStatement>nil() : forInit();
1711             if (inits.length() == 1 &&
1712                 inits.head.hasTag(VARDEF) &&
1713                 ((JCVariableDecl) inits.head).init == null &&
1714                 token.kind == COLON) {
1715                 checkForeach();
1716                 JCVariableDecl var = (JCVariableDecl)inits.head;
1717                 accept(COLON);
1718                 JCExpression expr = parseExpression();
1719                 accept(RPAREN);
1720                 JCStatement body = parseStatement();
1721                 return F.at(pos).ForeachLoop(var, expr, body);
1722             } else {
1723                 accept(SEMI);
1724                 JCExpression cond = token.kind == SEMI ? null : parseExpression();
1725                 accept(SEMI);
1726                 List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
1727                 accept(RPAREN);
1728                 JCStatement body = parseStatement();
1729                 return F.at(pos).ForLoop(inits, cond, steps, body);
1730             }
1731         }
1732         case WHILE: {


1825             return toP(F.Exec(syntaxError("catch.without.try")));
1826         case ASSERT: {
1827             if (allowAsserts && token.kind == ASSERT) {
1828                 nextToken();
1829                 JCExpression assertion = parseExpression();
1830                 JCExpression message = null;
1831                 if (token.kind == COLON) {
1832                     nextToken();
1833                     message = parseExpression();
1834                 }
1835                 JCAssert t = to(F.at(pos).Assert(assertion, message));
1836                 accept(SEMI);
1837                 return t;
1838             }
1839             /* else fall through to default case */
1840         }
1841         case ENUM:
1842         default:
1843             Token prevToken = token;
1844             JCExpression expr = parseExpression();
1845             if (token.kind == COLON && expr.hasTag(IDENT)) {
1846                 nextToken();
1847                 JCStatement stat = parseStatement();
1848                 return F.at(pos).Labelled(prevToken.name(), stat);
1849             } else {
1850                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1851                 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
1852                 accept(SEMI);
1853                 return stat;
1854             }
1855         }
1856     }
1857 
1858     /** CatchClause     = CATCH "(" FormalParameter ")" Block
1859      */
1860     protected JCCatch catchClause() {
1861         int pos = token.pos;
1862         accept(CATCH);
1863         accept(LPAREN);
1864         JCModifiers mods = optFinal(Flags.PARAMETER);
1865         List<JCExpression> catchTypes = catchTypes();


2078         accept(LPAREN);
2079         ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2080         if (token.kind != RPAREN) {
2081             buf.append(annotationFieldValue());
2082             while (token.kind == COMMA) {
2083                 nextToken();
2084                 buf.append(annotationFieldValue());
2085             }
2086         }
2087         accept(RPAREN);
2088         return buf.toList();
2089     }
2090 
2091     /** AnnotationFieldValue    = AnnotationValue
2092      *                          | Identifier "=" AnnotationValue
2093      */
2094     JCExpression annotationFieldValue() {
2095         if (token.kind == IDENTIFIER) {
2096             mode = EXPR;
2097             JCExpression t1 = term1();
2098             if (t1.hasTag(IDENT) && token.kind == EQ) {
2099                 int pos = token.pos;
2100                 accept(EQ);
2101                 JCExpression v = annotationValue();
2102                 return toP(F.at(pos).Assign(t1, v));
2103             } else {
2104                 return t1;
2105             }
2106         }
2107         return annotationValue();
2108     }
2109 
2110     /* AnnotationValue          = ConditionalExpression
2111      *                          | Annotation
2112      *                          | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
2113      */
2114     JCExpression annotationValue() {
2115         int pos;
2116         switch (token.kind) {
2117         case MONKEYS_AT:
2118             pos = token.pos;


2608                 return List.<JCTree>of(block(pos, mods.flags));
2609             } else {
2610                 pos = token.pos;
2611                 List<JCTypeParameter> typarams = typeParametersOpt();
2612                 // if there are type parameters but no modifiers, save the start
2613                 // position of the method in the modifiers.
2614                 if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
2615                     mods.pos = pos;
2616                     storeEnd(mods, pos);
2617                 }
2618                 Token tk = token;
2619                 pos = token.pos;
2620                 JCExpression type;
2621                 boolean isVoid = token.kind == VOID;
2622                 if (isVoid) {
2623                     type = to(F.at(pos).TypeIdent(TypeTags.VOID));
2624                     nextToken();
2625                 } else {
2626                     type = parseType();
2627                 }
2628                 if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
2629                     if (isInterface || tk.name() != className)
2630                         error(pos, "invalid.meth.decl.ret.type.req");
2631                     return List.of(methodDeclaratorRest(
2632                         pos, mods, null, names.init, typarams,
2633                         isInterface, true, dc));
2634                 } else {
2635                     pos = token.pos;
2636                     Name name = ident();
2637                     if (token.kind == LPAREN) {
2638                         return List.of(methodDeclaratorRest(
2639                             pos, mods, type, name, typarams,
2640                             isInterface, isVoid, dc));
2641                     } else if (!isVoid && typarams.isEmpty()) {
2642                         List<JCTree> defs =
2643                             variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
2644                                                     new ListBuffer<JCTree>()).toList();
2645                         storeEnd(defs.last(), token.endPos);
2646                         accept(SEMI);
2647                         return defs;
2648                     } else {


2805     }
2806 
2807 /* ---------- auxiliary methods -------------- */
2808 
2809     void error(int pos, String key, Object ... args) {
2810         log.error(DiagnosticFlag.SYNTAX, pos, key, args);
2811     }
2812 
2813     void error(DiagnosticPosition pos, String key, Object ... args) {
2814         log.error(DiagnosticFlag.SYNTAX, pos, key, args);
2815     }
2816 
2817     void warning(int pos, String key, Object ... args) {
2818         log.warning(pos, key, args);
2819     }
2820 
2821     /** Check that given tree is a legal expression statement.
2822      */
2823     protected JCExpression checkExprStat(JCExpression t) {
2824         switch(t.getTag()) {
2825         case PREINC: case PREDEC:
2826         case POSTINC: case POSTDEC:
2827         case ASSIGN:
2828         case BITOR_ASG: case BITXOR_ASG: case BITAND_ASG:
2829         case SL_ASG: case SR_ASG: case USR_ASG:
2830         case PLUS_ASG: case MINUS_ASG:
2831         case MUL_ASG: case DIV_ASG: case MOD_ASG:
2832         case APPLY: case NEWCLASS:
2833         case ERRONEOUS:
2834             return t;
2835         default:
2836             JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
2837             error(ret, "not.stmt");
2838             return ret;
2839         }
2840     }
2841 
2842     /** Return precedence of operator represented by token,
2843      *  -1 if token is not a binary operator. @see TreeInfo.opPrec
2844      */
2845     static int prec(TokenKind token) {
2846         JCTree.Tag oc = optag(token);
2847         return (oc.ordinal() > NO_TAG.ordinal()) ? TreeInfo.opPrec(oc) : -1;
2848     }
2849 
2850     /**
2851      * Return the lesser of two positions, making allowance for either one
2852      * being unset.
2853      */
2854     static int earlier(int pos1, int pos2) {
2855         if (pos1 == Position.NOPOS)
2856             return pos2;
2857         if (pos2 == Position.NOPOS)
2858             return pos1;
2859         return (pos1 < pos2 ? pos1 : pos2);
2860     }
2861 
2862     /** Return operation tag of binary operator represented by token,
2863      *  No_TAG if token is not a binary operator.
2864      */
2865     static JCTree.Tag optag(TokenKind token) {
2866         switch (token) {
2867         case BARBAR:
2868             return OR;
2869         case AMPAMP:
2870             return AND;
2871         case BAR:
2872             return BITOR;
2873         case BAREQ:
2874             return BITOR_ASG;
2875         case CARET:
2876             return BITXOR;
2877         case CARETEQ:
2878             return BITXOR_ASG;
2879         case AMP:
2880             return BITAND;
2881         case AMPEQ:
2882             return BITAND_ASG;
2883         case EQEQ:
2884             return JCTree.Tag.EQ;
2885         case BANGEQ:
2886             return NE;
2887         case LT:
2888             return JCTree.Tag.LT;
2889         case GT:
2890             return JCTree.Tag.GT;
2891         case LTEQ:
2892             return LE;
2893         case GTEQ:
2894             return GE;
2895         case LTLT:
2896             return SL;
2897         case LTLTEQ:
2898             return SL_ASG;
2899         case GTGT:
2900             return SR;
2901         case GTGTEQ:
2902             return SR_ASG;
2903         case GTGTGT:
2904             return USR;
2905         case GTGTGTEQ:
2906             return USR_ASG;
2907         case PLUS:
2908             return JCTree.Tag.PLUS;
2909         case PLUSEQ:
2910             return PLUS_ASG;
2911         case SUB:
2912             return MINUS;
2913         case SUBEQ:
2914             return MINUS_ASG;
2915         case STAR:
2916             return MUL;
2917         case STAREQ:
2918             return MUL_ASG;
2919         case SLASH:
2920             return DIV;
2921         case SLASHEQ:
2922             return DIV_ASG;
2923         case PERCENT:
2924             return MOD;
2925         case PERCENTEQ:
2926             return MOD_ASG;
2927         case INSTANCEOF:
2928             return TYPETEST;
2929         default:
2930             return NO_TAG;
2931         }
2932     }
2933 
2934     /** Return operation tag of unary operator represented by token,
2935      *  No_TAG if token is not a binary operator.
2936      */
2937     static JCTree.Tag unoptag(TokenKind token) {
2938         switch (token) {
2939         case PLUS:
2940             return POS;
2941         case SUB:
2942             return NEG;
2943         case BANG:
2944             return NOT;
2945         case TILDE:
2946             return COMPL;
2947         case PLUSPLUS:
2948             return PREINC;
2949         case SUBSUB:
2950             return PREDEC;
2951         default:
2952             return NO_TAG;
2953         }
2954     }
2955 
2956     /** Return type tag of basic type represented by token,
2957      *  -1 if token is not a basic type identifier.
2958      */
2959     static int typetag(TokenKind token) {
2960         switch (token) {
2961         case BYTE:
2962             return TypeTags.BYTE;
2963         case CHAR:
2964             return TypeTags.CHAR;
2965         case SHORT:
2966             return TypeTags.SHORT;
2967         case INT:
2968             return TypeTags.INT;
2969         case LONG:
2970             return TypeTags.LONG;
2971         case FLOAT:
2972             return TypeTags.FLOAT;