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 


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

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


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







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




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


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

































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


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






3225 }


 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.allowTWR = source.allowTryWithResources();
 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 allowTWR;
 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 


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


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


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


3255         }
3256     }
3257     void checkTypeAnnotations() {
3258         if (!allowTypeAnnotations) {
3259             log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3260             allowTypeAnnotations = true;
3261         }
3262     }
3263     void checkDiamond() {
3264         if (!allowDiamond) {
3265             log.error(S.pos(), "diamond.not.supported.in.source", source.name);
3266             allowDiamond = true;
3267         }
3268     }
3269     void checkMulticatch() {
3270         if (!allowMulticatch) {
3271             log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
3272             allowMulticatch = true;
3273         }
3274     }
3275     void checkAutomaticResourceManagement() {
3276         if (!allowTWR) {
3277             log.error(S.pos(), "automatic.resource.management.not.supported.in.source", source.name);
3278             allowTWR = true;
3279         }
3280     }
3281 }