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

Print this page




 114     /** Construct a parser from a given scanner, tree factory and log.
 115      */
 116     protected JavacParser(ParserFactory fac,
 117                      Lexer S,
 118                      boolean keepDocComments,
 119                      boolean keepLineMap) {
 120         this.S = S;
 121         S.nextToken(); // prime the pump
 122         this.F = fac.F;
 123         this.log = fac.log;
 124         this.names = fac.names;
 125         this.keywords = fac.keywords;
 126         this.source = fac.source;
 127         this.allowGenerics = source.allowGenerics();
 128         this.allowVarargs = source.allowVarargs();
 129         this.allowAsserts = source.allowAsserts();
 130         this.allowEnums = source.allowEnums();
 131         this.allowForeach = source.allowForeach();
 132         this.allowStaticImport = source.allowStaticImport();
 133         this.allowAnnotations = source.allowAnnotations();

 134         this.allowDiamond = source.allowDiamond();
 135         this.allowMulticatch = source.allowMulticatch();
 136         this.allowTypeAnnotations = source.allowTypeAnnotations();
 137         this.keepDocComments = keepDocComments;
 138         if (keepDocComments)
 139             docComments = new HashMap<JCTree,String>();
 140         this.keepLineMap = keepLineMap;
 141         this.errorTree = F.Erroneous();
 142         this.debugJSR308 = fac.options.get("TA:parser") != null;
 143     }
 144 
 145     /** Switch: debug output for type-annotations operations
 146      */
 147     boolean debugJSR308;
 148 
 149     /** Switch: Should generics be recognized?
 150      */
 151     boolean allowGenerics;
 152 
 153     /** Switch: Should diamond operator be recognized?


 169     /** Switch: should we recognize enums, or just give a warning?
 170      */
 171     boolean allowEnums;
 172 
 173     /** Switch: should we recognize foreach?
 174      */
 175     boolean allowForeach;
 176 
 177     /** Switch: should we recognize foreach?
 178      */
 179     boolean allowStaticImport;
 180 
 181     /** Switch: should we recognize annotations?
 182      */
 183     boolean allowAnnotations;
 184 
 185     /** Switch: should we recognize type annotations?
 186      */
 187     boolean allowTypeAnnotations;
 188 




 189     /** Switch: should we keep docComments?
 190      */
 191     boolean keepDocComments;
 192 
 193     /** Switch: should we keep line table?
 194      */
 195     boolean keepLineMap;
 196 
 197     /** When terms are parsed, the mode determines which is expected:
 198      *     mode = EXPR        : an expression
 199      *     mode = TYPE        : a type
 200      *     mode = NOPARAMS    : no parameters allowed for type
 201      *     mode = TYPEARG     : type argument
 202      */
 203     static final int EXPR = 0x1;
 204     static final int TYPE = 0x2;
 205     static final int NOPARAMS = 0x4;
 206     static final int TYPEARG = 0x8;
 207     static final int DIAMOND = 0x10;
 208 


1825             if (S.pos() == lastErrPos)
1826                 return stats.toList();
1827             if (S.pos() <= errorEndPos) {
1828                 skip(false, true, true, true);
1829                 lastErrPos = S.pos();
1830             }
1831 
1832             // ensure no dangling /** @deprecated */ active
1833             S.resetDeprecatedFlag();
1834         }
1835     }
1836 
1837     /** Statement =
1838      *       Block
1839      *     | IF ParExpression Statement [ELSE Statement]
1840      *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
1841      *     | FOR "(" FormalParameter : Expression ")" Statement
1842      *     | WHILE ParExpression Statement
1843      *     | DO Statement WHILE ParExpression ";"
1844      *     | TRY Block ( Catches | [Catches] FinallyPart )

1845      *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
1846      *     | SYNCHRONIZED ParExpression Block
1847      *     | RETURN [Expression] ";"
1848      *     | THROW Expression ";"
1849      *     | BREAK [Ident] ";"
1850      *     | CONTINUE [Ident] ";"
1851      *     | ASSERT Expression [ ":" Expression ] ";"
1852      *     | ";"
1853      *     | ExpressionStatement
1854      *     | Ident ":" Statement
1855      */
1856     @SuppressWarnings("fallthrough")
1857     public JCStatement parseStatement() {
1858         int pos = S.pos();
1859         switch (S.token()) {
1860         case LBRACE:
1861             return block();
1862         case IF: {
1863             S.nextToken();
1864             JCExpression cond = parExpression();


1895                 return F.at(pos).ForLoop(inits, cond, steps, body);
1896             }
1897         }
1898         case WHILE: {
1899             S.nextToken();
1900             JCExpression cond = parExpression();
1901             JCStatement body = parseStatement();
1902             return F.at(pos).WhileLoop(cond, body);
1903         }
1904         case DO: {
1905             S.nextToken();
1906             JCStatement body = parseStatement();
1907             accept(WHILE);
1908             JCExpression cond = parExpression();
1909             JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
1910             accept(SEMI);
1911             return t;
1912         }
1913         case TRY: {
1914             S.nextToken();







1915             JCBlock body = block();
1916             ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
1917             JCBlock finalizer = null;
1918             if (S.token() == CATCH || S.token() == FINALLY) {
1919                 while (S.token() == CATCH) catchers.append(catchClause());
1920                 if (S.token() == FINALLY) {
1921                     S.nextToken();
1922                     finalizer = block();
1923                 }
1924             } else {




1925                 log.error(pos, "try.without.catch.or.finally");
1926             }
1927             return F.at(pos).Try(body, catchers.toList(), finalizer);
1928         }
1929         case SWITCH: {
1930             S.nextToken();
1931             JCExpression selector = parExpression();
1932             accept(LBRACE);
1933             List<JCCase> cases = switchBlockStatementGroups();
1934             JCSwitch t = to(F.at(pos).Switch(selector, cases));
1935             accept(RBRACE);
1936             return t;
1937         }
1938         case SYNCHRONIZED: {
1939             S.nextToken();
1940             JCExpression lock = parExpression();
1941             JCBlock body = block();
1942             return F.at(pos).Synchronized(lock, body);
1943         }
1944         case RETURN: {
1945             S.nextToken();
1946             JCExpression result = S.token() == SEMI ? null : parseExpression();
1947             JCReturn t = to(F.at(pos).Return(result));


2368             S.nextToken();
2369             init = variableInitializer();
2370         }
2371         else if (reqInit) syntaxError(S.pos(), "expected", EQ);
2372         JCVariableDecl result =
2373             toP(F.at(pos).VarDef(mods, name, type, init));
2374         attach(result, dc);
2375         return result;
2376     }
2377 
2378     /** VariableDeclaratorId = Ident BracketsOpt
2379      */
2380     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2381         int pos = S.pos();
2382         Name name = ident();
2383         if ((mods.flags & Flags.VARARGS) == 0)
2384             type = bracketsOpt(type);
2385         return toP(F.at(pos).VarDef(mods, name, type, null));
2386     }
2387 






























2388     /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2389      */
2390     public JCTree.JCCompilationUnit parseCompilationUnit() {
2391         int pos = S.pos();
2392         JCExpression pid = null;
2393         String dc = S.docComment();
2394         JCModifiers mods = null;
2395         List<JCAnnotation> packageAnnotations = List.nil();
2396         if (S.token() == MONKEYS_AT)
2397             mods = modifiersOpt();
2398 
2399         if (S.token() == PACKAGE) {
2400             if (mods != null) {
2401                 checkNoMods(mods.flags);
2402                 packageAnnotations = mods.annotations;
2403                 mods = null;
2404             }
2405             S.nextToken();
2406             pid = qualident();
2407             accept(SEMI);


3201         }
3202     }
3203     void checkTypeAnnotations() {
3204         if (!allowTypeAnnotations) {
3205             log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3206             allowTypeAnnotations = true;
3207         }
3208     }
3209     void checkDiamond() {
3210         if (!allowDiamond) {
3211             log.error(S.pos(), "diamond.not.supported.in.source", source.name);
3212             allowDiamond = true;
3213         }
3214     }
3215     void checkMulticatch() {
3216         if (!allowMulticatch) {
3217             log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
3218             allowMulticatch = true;
3219             }
3220     }






3221 }


 114     /** Construct a parser from a given scanner, tree factory and log.
 115      */
 116     protected JavacParser(ParserFactory fac,
 117                      Lexer S,
 118                      boolean keepDocComments,
 119                      boolean keepLineMap) {
 120         this.S = S;
 121         S.nextToken(); // prime the pump
 122         this.F = fac.F;
 123         this.log = fac.log;
 124         this.names = fac.names;
 125         this.keywords = fac.keywords;
 126         this.source = fac.source;
 127         this.allowGenerics = source.allowGenerics();
 128         this.allowVarargs = source.allowVarargs();
 129         this.allowAsserts = source.allowAsserts();
 130         this.allowEnums = source.allowEnums();
 131         this.allowForeach = source.allowForeach();
 132         this.allowStaticImport = source.allowStaticImport();
 133         this.allowAnnotations = source.allowAnnotations();
 134         this.allowARM = source.allowAutomaticResourceManagement();
 135         this.allowDiamond = source.allowDiamond();
 136         this.allowMulticatch = source.allowMulticatch();
 137         this.allowTypeAnnotations = source.allowTypeAnnotations();
 138         this.keepDocComments = keepDocComments;
 139         if (keepDocComments)
 140             docComments = new HashMap<JCTree,String>();
 141         this.keepLineMap = keepLineMap;
 142         this.errorTree = F.Erroneous();
 143         this.debugJSR308 = fac.options.get("TA:parser") != null;
 144     }
 145 
 146     /** Switch: debug output for type-annotations operations
 147      */
 148     boolean debugJSR308;
 149 
 150     /** Switch: Should generics be recognized?
 151      */
 152     boolean allowGenerics;
 153 
 154     /** Switch: Should diamond operator be recognized?


 170     /** Switch: should we recognize enums, or just give a warning?
 171      */
 172     boolean allowEnums;
 173 
 174     /** Switch: should we recognize foreach?
 175      */
 176     boolean allowForeach;
 177 
 178     /** Switch: should we recognize foreach?
 179      */
 180     boolean allowStaticImport;
 181 
 182     /** Switch: should we recognize annotations?
 183      */
 184     boolean allowAnnotations;
 185 
 186     /** Switch: should we recognize type annotations?
 187      */
 188     boolean allowTypeAnnotations;
 189 
 190     /** Switch: should we recognize automatic resource management?
 191      */
 192     boolean allowARM;
 193 
 194     /** Switch: should we keep docComments?
 195      */
 196     boolean keepDocComments;
 197 
 198     /** Switch: should we keep line table?
 199      */
 200     boolean keepLineMap;
 201 
 202     /** When terms are parsed, the mode determines which is expected:
 203      *     mode = EXPR        : an expression
 204      *     mode = TYPE        : a type
 205      *     mode = NOPARAMS    : no parameters allowed for type
 206      *     mode = TYPEARG     : type argument
 207      */
 208     static final int EXPR = 0x1;
 209     static final int TYPE = 0x2;
 210     static final int NOPARAMS = 0x4;
 211     static final int TYPEARG = 0x8;
 212     static final int DIAMOND = 0x10;
 213 


1830             if (S.pos() == lastErrPos)
1831                 return stats.toList();
1832             if (S.pos() <= errorEndPos) {
1833                 skip(false, true, true, true);
1834                 lastErrPos = S.pos();
1835             }
1836 
1837             // ensure no dangling /** @deprecated */ active
1838             S.resetDeprecatedFlag();
1839         }
1840     }
1841 
1842     /** Statement =
1843      *       Block
1844      *     | IF ParExpression Statement [ELSE Statement]
1845      *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
1846      *     | FOR "(" FormalParameter : Expression ")" Statement
1847      *     | WHILE ParExpression Statement
1848      *     | DO Statement WHILE ParExpression ";"
1849      *     | TRY Block ( Catches | [Catches] FinallyPart )
1850      *     | TRY "(" ResourceSpecification ")" Block [Catches] [FinallyPart]
1851      *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
1852      *     | SYNCHRONIZED ParExpression Block
1853      *     | RETURN [Expression] ";"
1854      *     | THROW Expression ";"
1855      *     | BREAK [Ident] ";"
1856      *     | CONTINUE [Ident] ";"
1857      *     | ASSERT Expression [ ":" Expression ] ";"
1858      *     | ";"
1859      *     | ExpressionStatement
1860      *     | Ident ":" Statement
1861      */
1862     @SuppressWarnings("fallthrough")
1863     public JCStatement parseStatement() {
1864         int pos = S.pos();
1865         switch (S.token()) {
1866         case LBRACE:
1867             return block();
1868         case IF: {
1869             S.nextToken();
1870             JCExpression cond = parExpression();


1901                 return F.at(pos).ForLoop(inits, cond, steps, body);
1902             }
1903         }
1904         case WHILE: {
1905             S.nextToken();
1906             JCExpression cond = parExpression();
1907             JCStatement body = parseStatement();
1908             return F.at(pos).WhileLoop(cond, body);
1909         }
1910         case DO: {
1911             S.nextToken();
1912             JCStatement body = parseStatement();
1913             accept(WHILE);
1914             JCExpression cond = parExpression();
1915             JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
1916             accept(SEMI);
1917             return t;
1918         }
1919         case TRY: {
1920             S.nextToken();
1921             List<JCTree> resources = List.<JCTree>nil();
1922             if (S.token() == LPAREN) {
1923                 checkAutomaticResourceManagement();
1924                 S.nextToken();
1925                 resources = resourceDeclarators();
1926                 accept(RPAREN);
1927             }
1928             JCBlock body = block();
1929             ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
1930             JCBlock finalizer = null;
1931             if (S.token() == CATCH || S.token() == FINALLY) {
1932                 while (S.token() == CATCH) catchers.append(catchClause());
1933                 if (S.token() == FINALLY) {
1934                     S.nextToken();
1935                     finalizer = block();
1936                 }
1937             } else {
1938                 if (allowARM) {
1939                     if (resources.isEmpty())
1940                         log.error(pos, "try.without.catch.finally.or.resource.decls");
1941                 } else
1942                     log.error(pos, "try.without.catch.or.finally");
1943             }
1944             return F.at(pos).Try(body, catchers.toList(), finalizer, resources);
1945         }
1946         case SWITCH: {
1947             S.nextToken();
1948             JCExpression selector = parExpression();
1949             accept(LBRACE);
1950             List<JCCase> cases = switchBlockStatementGroups();
1951             JCSwitch t = to(F.at(pos).Switch(selector, cases));
1952             accept(RBRACE);
1953             return t;
1954         }
1955         case SYNCHRONIZED: {
1956             S.nextToken();
1957             JCExpression lock = parExpression();
1958             JCBlock body = block();
1959             return F.at(pos).Synchronized(lock, body);
1960         }
1961         case RETURN: {
1962             S.nextToken();
1963             JCExpression result = S.token() == SEMI ? null : parseExpression();
1964             JCReturn t = to(F.at(pos).Return(result));


2385             S.nextToken();
2386             init = variableInitializer();
2387         }
2388         else if (reqInit) syntaxError(S.pos(), "expected", EQ);
2389         JCVariableDecl result =
2390             toP(F.at(pos).VarDef(mods, name, type, init));
2391         attach(result, dc);
2392         return result;
2393     }
2394 
2395     /** VariableDeclaratorId = Ident BracketsOpt
2396      */
2397     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2398         int pos = S.pos();
2399         Name name = ident();
2400         if ((mods.flags & Flags.VARARGS) == 0)
2401             type = bracketsOpt(type);
2402         return toP(F.at(pos).VarDef(mods, name, type, null));
2403     }
2404 
2405     /** ResourceDeclarators = ResourceDeclarator { ";" ResourceDeclarator }
2406      */
2407     List<JCTree> resourceDeclarators() {
2408         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2409         defs.append(resourceDeclarator());
2410         while (S.token() == SEMI) {
2411             // All but last of multiple declarators subsume a semicolon
2412             storeEnd(defs.elems.last(), S.endPos());
2413             S.nextToken();
2414             defs.append(resourceDeclarator());
2415         }
2416         return defs.toList();
2417     }
2418 
2419     /** ResourceDeclarator = LocalVariableDeclaration */
2420     JCTree resourceDeclarator() {
2421         int pos = S.pos();
2422         if (S.token() == FINAL || S.token() == MONKEYS_AT) {
2423             return variableDeclaratorRest(pos, optFinal(0), parseType(),
2424                                           ident(), true, null);
2425         } else {
2426             JCExpression t = term(EXPR | TYPE);
2427             if ((lastmode & TYPE) != 0 && S.token() == IDENTIFIER)
2428                 return variableDeclaratorRest(pos, toP(F.at(pos).Modifiers(Flags.FINAL)), t,
2429                                               ident(), true, null);
2430             else
2431                 return t;
2432         }
2433     }
2434 
2435     /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2436      */
2437     public JCTree.JCCompilationUnit parseCompilationUnit() {
2438         int pos = S.pos();
2439         JCExpression pid = null;
2440         String dc = S.docComment();
2441         JCModifiers mods = null;
2442         List<JCAnnotation> packageAnnotations = List.nil();
2443         if (S.token() == MONKEYS_AT)
2444             mods = modifiersOpt();
2445 
2446         if (S.token() == PACKAGE) {
2447             if (mods != null) {
2448                 checkNoMods(mods.flags);
2449                 packageAnnotations = mods.annotations;
2450                 mods = null;
2451             }
2452             S.nextToken();
2453             pid = qualident();
2454             accept(SEMI);


3248         }
3249     }
3250     void checkTypeAnnotations() {
3251         if (!allowTypeAnnotations) {
3252             log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3253             allowTypeAnnotations = true;
3254         }
3255     }
3256     void checkDiamond() {
3257         if (!allowDiamond) {
3258             log.error(S.pos(), "diamond.not.supported.in.source", source.name);
3259             allowDiamond = true;
3260         }
3261     }
3262     void checkMulticatch() {
3263         if (!allowMulticatch) {
3264             log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
3265             allowMulticatch = true;
3266             }
3267     }
3268     void checkAutomaticResourceManagement() {
3269         if (!allowARM) {
3270             log.error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name);
3271             allowARM = true;
3272         }
3273     }
3274 }