⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.java

📁 java编译器gjc源码 java编译环境
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                        (S.token == IDENTIFIER || S.token == ASSERT)) {
                    stats.appendList(variableDeclarators(0, t));
                    accept(SEMI);
                } else {
                    stats.append(F.at(pos).Exec(checkExprStat(t)));
                    accept(SEMI);
                }

            }
        }
    }

    /**
      * Statement =
      *       Block
      *     | IF ParExpression Statement [ELSE Statement]
      *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
      *     | WHILE ParExpression Statement
      *     | DO Statement WHILE ParExpression ";"
      *     | TRY Block ( Catches | [Catches] FinallyPart )
      *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
      *     | SYNCHRONIZED ParExpression Block
      *     | RETURN [Expression] ";"
      *     | THROW Expression ";"
      *     | BREAK [Ident] ";"
      *     | CONTINUE [Ident] ";"
      *     | ASSERT Expression [ ":" Expression ] ";"
      *     | ";"
      *     | ExpressionStatement
      *     | Ident ":" Statement
      */
    Tree statement() {
        int pos = S.pos;
        switch (S.token) {
        case LBRACE:
            return block();

        case IF:
            {
                S.nextToken();
                Tree cond = parExpression();
                Tree thenpart = statement();
                Tree elsepart = null;
                if (S.token == ELSE) {
                    S.nextToken();
                    elsepart = statement();
                }
                return F.at(pos).If(cond, thenpart, elsepart);
            }

        case FOR:
            {
                S.nextToken();
                accept(LPAREN);
                List inits = S.token == SEMI ? Tree.emptyList : forInit();
                accept(SEMI);
                Tree cond = S.token == SEMI ? null : expression();
                accept(SEMI);
                List steps = S.token == RPAREN ? Tree.emptyList : forUpdate();
                accept(RPAREN);
                Tree body = statement();
                return F.at(pos).ForLoop(inits, cond, steps, body);
            }

        case WHILE:
            {
                S.nextToken();
                Tree cond = parExpression();
                Tree body = statement();
                return F.at(pos).WhileLoop(cond, body);
            }

        case DO:
            {
                S.nextToken();
                Tree body = statement();
                accept(WHILE);
                Tree cond = parExpression();
                Tree t = F.at(pos).DoLoop(body, cond);
                if (genEndPos)
                    endPositions.put(t, new Integer(S.endPos));
                accept(SEMI);
                return t;
            }

        case TRY:
            {
                S.nextToken();
                Tree body = block();
                ListBuffer catchers = new ListBuffer();
                Tree finalizer = null;
                if (S.token == CATCH || S.token == FINALLY) {
                    while (S.token == CATCH)
                        catchers.append(catchClause());
                    if (S.token == FINALLY) {
                        S.nextToken();
                        finalizer = block();
                    }
                } else {
                    log.error(pos, "try.without.catch.or.finally");
                }
                return F.at(pos).Try(body, catchers.toList(), finalizer);
            }

        case SWITCH:
            {
                S.nextToken();
                Tree selector = parExpression();
                accept(LBRACE);
                List cases = switchBlockStatementGroups();
                Tree t = F.at(pos).Switch(selector, cases);
                if (genEndPos)
                    endPositions.put(t, new Integer(S.endPos));
                accept(RBRACE);
                return t;
            }

        case SYNCHRONIZED:
            {
                S.nextToken();
                Tree lock = parExpression();
                Tree body = block();
                return F.at(pos).Synchronized(lock, body);
            }

        case RETURN:
            {
                S.nextToken();
                Tree result = S.token == SEMI ? null : expression();
                Tree t = F.at(pos).Return(result);
                if (genEndPos)
                    endPositions.put(t, new Integer(S.endPos));
                accept(SEMI);
                return t;
            }

        case THROW:
            {
                S.nextToken();
                Tree exc = expression();
                Tree t = F.at(pos).Throw(exc);
                if (genEndPos)
                    endPositions.put(t, new Integer(S.endPos));
                accept(SEMI);
                return t;
            }

        case BREAK:
            {
                S.nextToken();
                Name label = (S.token == IDENTIFIER || S.token == ASSERT) ? ident() :
                        null;
                Tree t = F.at(pos).Break(label);
                if (genEndPos)
                    endPositions.put(t, new Integer(S.prevEndPos));
                accept(SEMI);
                return t;
            }

        case CONTINUE:
            {
                S.nextToken();
                Name label = (S.token == IDENTIFIER || S.token == ASSERT) ? ident() :
                        null;
                Tree t = F.at(pos).Continue(label);
                if (genEndPos)
                    endPositions.put(t, new Integer(S.prevEndPos));
                accept(SEMI);
                return t;
            }

        case SEMI:
            S.nextToken();
            return F.at(pos).Skip();

        case ELSE:
            return syntaxError("else.without.if");

        case FINALLY:
            return syntaxError("finally.without.try");

        case CATCH:
            return syntaxError("catch.without.try");

        case ASSERT:
            {
                if (allowAsserts) {
                    S.nextToken();
                    Tree assertion = expression();
                    Tree message = null;
                    if (S.token == COLON) {
                        S.nextToken();
                        message = expression();
                    }
                    Tree t = F.at(pos).Assert(assertion, message);
                    accept(SEMI);
                    return t;
                }
            }

        default:
            Name name = S.name;
            Tree expr = expression();
            if (S.token == COLON && expr.tag == Tree.IDENT) {
                S.nextToken();
                Tree stat = statement();
                return F.at(pos).Labelled(name, stat);
            } else {
                Tree stat = F.at(pos).Exec(checkExprStat(expr));
                accept(SEMI);
                return stat;
            }

        }
    }

    /**
      * CatchClause	= CATCH "(" FormalParameter ")" Block
      */
    Catch catchClause() {
        int pos = S.pos;
        accept(CATCH);
        accept(LPAREN);
        VarDef formal =
                variableDeclaratorId(optFinal() | Flags.PARAMETER, qualident());
        accept(RPAREN);
        Tree body = block();
        return F.at(pos).Catch(formal, body);
    }

    /**
      * SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
      */
    List switchBlockStatementGroups() {
        ListBuffer cases = new ListBuffer();
        while (true) {
            int pos = S.pos;
            switch (S.token) {
            case CASE:
                {
                    S.nextToken();
                    Tree pat = expression();
                    accept(COLON);
                    List stats = blockStatements();
                    cases.append(F.at(pos).Case(pat, stats));
                    break;
                }

            case DEFAULT:
                {
                    S.nextToken();
                    accept(COLON);
                    List stats = blockStatements();
                    cases.append(F.at(pos).Case(null, stats));
                    break;
                }

            case RBRACE:

            case EOF:
                return cases.toList();

            default:
                S.nextToken();
                syntaxError(pos, "case.default.or.right-brace.expected");

            }
        }
    }

    /**
      * MoreStatementExpressions = { COMMA StatementExpression }
      */
    List moreStatementExpressions(int pos, Tree first) {
        ListBuffer stats = new ListBuffer();
        stats.append(F.at(pos).Exec(checkExprStat(first)));
        while (S.token == COMMA) {
            S.nextToken();
            pos = S.pos;
            Tree t = expression();
            stats.append(F.at(pos).Exec(checkExprStat(t)));
        }
        return stats.toList();
    }

    /**
      * ForInit = StatementExpression MoreStatementExpressions
      *           |  [FINAL] Type VariableDeclarators
      */
    List forInit() {
        int pos = S.pos;
        if (S.token == FINAL) {
            S.nextToken();
            return variableDeclarators(Flags.FINAL, type());
        } else {
            Tree t = term(EXPR | TYPE);
            if ((lastmode & TYPE) != 0 &&
                    (S.token == IDENTIFIER || S.token == ASSERT))
                return variableDeclarators(0, t);
            else
                return moreStatementExpressions(pos, t);
        }
    }

    /**
      * ForUpdate = StatementExpression MoreStatementExpressions
      */
    List forUpdate() {
        return moreStatementExpressions(S.pos, expression());
    }

    /**
      * ModifiersOpt = { Modifier }
      *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
      *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
      */
    long modifiersOpt() {
        long flags = 0;
        if (S.deprecatedFlag) {
            flags = Flags.DEPRECATED;
            S.deprecatedFlag = false;
        }
        while (true) {
            int flag;
            switch (S.token) {
            case PRIVATE:
                flag = Flags.PRIVATE;
                break;

            case PROTECTED:
                flag = Flags.PROTECTED;
                break;

            case PUBLIC:
                flag = Flags.PUBLIC;
                break;

            case STATIC:
                flag = Flags.STATIC;
                break;

            case TRANSIENT:
                flag = Flags.TRANSIENT;
                break;

            case FINAL:
                flag = Flags.FINAL;
                break;

            case ABSTRACT:
                flag = Flags.ABSTRACT;
                break;

            case NATIVE:
                flag = Flags.NATIVE;
                break;

            case VOLATILE:
                flag = Flags.VOLATILE;
                break;

            case SYNCHRONIZED:
                flag = Flags.SYNCHRONIZED;
                break;

            case STRICTFP:
                flag = Flags.STRICTFP;
                break;

            default:
                return flags;

            }
            if ((flags & flag) != 0)
                log.error(S.pos, "repeated.modifier");
            flags = flags | flag;
            S.nextToken();
        }
    }

    /**
      * VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
      */
    List variableDeclarators(long flags, Tree type) {
        return variableDeclaratorsRest(S.pos, flags, type, ident(), false, null);
    }

    /**
      * VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
      *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
      *
      *  @param reqInit  Is an initializer always required?
      *  @param dc       The documentation comment for the variable declarations, or null.
      */
    List variableDeclaratorsRest(int pos, long flags, Tree type, Name name,
            boolean reqInit, String dc) {
        ListBuffer vdefs = new ListBuffer();
        vdefs.append(variableDeclaratorRest(pos, flags, type, name, reqInit, dc));
        while (S.token == COMMA) {
            S.nextToken();
            vdefs.append(variableDeclarator(flags, type, reqInit, dc));
        }
        return vdefs.toList();
    }

    /**
      * VariableDeclarator = Ident VariableDeclaratorRest
      *  ConstantDeclarator = Ident ConstantDeclaratorRest
      */
    VarDef variableDeclarator(long flags, Tree type, boolean reqInit, String dc) {
        return variableDeclaratorRest(S.pos, flags, type, ident(), reqInit, dc);
    }

    /**
      * VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
      *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
      *
      *  @param reqInit  Is an initializer always required?
      *  @param dc       The documentation comment for the variable declarations, or null.
      */
    VarDef variableDeclaratorRest(int pos, long flags, Tree type, Name name,
            boolean reqInit, String dc) {
        type = bracketsOpt(type);
        Tree init = null;
        if (S.token == EQ) {
            S.nextToken();
            init = variableInitializer();
        } else if (reqInit)
            syntaxError(S.pos, "expected", keywords.token2string(EQ));
        VarDef result = F.at(pos).VarDef(flags, name, type, init);
        if (genEndPos)
            endPositions.put(result, new Integer(S.prevEndPos));
        attach(result, dc);
        return result;
    }

    /**
      * VariableDeclaratorId = Ident BracketsOpt

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -