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

📄 parser.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License.  Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */package javassist.compiler;import javassist.compiler.ast.*;public final class Parser implements TokenId {    private Lex lex;    public Parser(Lex lex) {        this.lex = lex;    }    public boolean hasMore() { return lex.lookAhead() >= 0; }    /* member.declaration     * : method.declaration | field.declaration     */    public ASTList parseMember(SymbolTable tbl) throws CompileError {        ASTList mem = parseMember1(tbl);        if (mem instanceof MethodDecl)            return parseMethod2(tbl, (MethodDecl)mem);        else            return mem;    }    /* A method body is not parsed.     */    public ASTList parseMember1(SymbolTable tbl) throws CompileError {        ASTList mods = parseMemberMods();        Declarator d;        boolean isConstructor = false;        if (lex.lookAhead() == Identifier && lex.lookAhead(1) == '(') {            d = new Declarator(VOID, 0);            isConstructor = true;        }        else            d = parseFormalType(tbl);        if (lex.get() != Identifier)            throw new SyntaxError(lex);        String name;        if (isConstructor)            name = MethodDecl.initName;        else            name = lex.getString();        d.setVariable(new Symbol(name));        if (isConstructor || lex.lookAhead() == '(')            return parseMethod1(tbl, isConstructor, mods, d);        else            return parseField(tbl, mods, d);    }    /* field.declaration     *  : member.modifiers     *    formal.type Identifier     *    [ "=" expression ] ";"     */    private FieldDecl parseField(SymbolTable tbl, ASTList mods,                                Declarator d) throws CompileError    {        ASTree expr = null;        if (lex.lookAhead() == '=') {            lex.get();            expr = parseExpression(tbl);        }        int c = lex.get();        if (c == ';')            return new FieldDecl(mods, new ASTList(d, new ASTList(expr)));        else if (c == ',')            throw new CompileError(                "only one field can be declared in one declaration", lex);        else            throw new SyntaxError(lex);    }    /* method.declaration     *  : member.modifiers     *    [ formal.type ]     *    Identifier "(" [ formal.parameter ( "," formal.parameter )* ] ")"     *    array.dimension     *    [ THROWS class.type ( "," class.type ) ]     *    ( block.statement | ";" )     *     * Note that a method body is not parsed.     */    private MethodDecl parseMethod1(SymbolTable tbl, boolean isConstructor,                                    ASTList mods, Declarator d)        throws CompileError    {        if (lex.get() != '(')            throw new SyntaxError(lex);        ASTList parms = null;        if (lex.lookAhead() != ')')            while (true) {                parms = ASTList.append(parms, parseFormalParam(tbl));                int t = lex.lookAhead();                if (t == ',')                    lex.get();                else if (t == ')')                    break;            }        lex.get();      // ')'        d.addArrayDim(parseArrayDimension());        if (isConstructor && d.getArrayDim() > 0)            throw new SyntaxError(lex);        ASTList throwsList = null;        if (lex.lookAhead() == THROWS) {            lex.get();            while (true) {                throwsList = ASTList.append(throwsList, parseClassType(tbl));                if (lex.lookAhead() == ',')                    lex.get();                else                    break;            }        }        return new MethodDecl(mods, new ASTList(d,                                ASTList.make(parms, throwsList, null)));    }    /* Parses a method body.     */    public MethodDecl parseMethod2(SymbolTable tbl, MethodDecl md)        throws CompileError    {        Stmnt body = null;        if (lex.lookAhead() == ';')            lex.get();        else {            body = parseBlock(tbl);            if (body == null)                body = new Stmnt(BLOCK);        }        md.sublist(4).setHead(body);        return md;    }    /* member.modifiers     *  : ( FINAL | SYNCHRONIZED | ABSTRACT     *    | PUBLIC | PROTECTED | PRIVATE | STATIC     *    | VOLATILE | TRANSIENT | STRICT )*     */    private ASTList parseMemberMods() {        int t;        ASTList list = null;        while (true) {            t = lex.lookAhead();            if (t == ABSTRACT || t == FINAL || t == PUBLIC || t == PROTECTED                || t == PRIVATE || t == SYNCHRONIZED || t == STATIC                || t == VOLATILE || t == TRANSIENT || t == STRICT)                list = new ASTList(new Keyword(lex.get()), list);            else                break;        }        return list;    }    /* formal.type : ( build-in-type | class.type ) array.dimension     */    private Declarator parseFormalType(SymbolTable tbl) throws CompileError {        int t = lex.lookAhead();        if (isBuiltinType(t) || t == VOID) {            lex.get();  // primitive type            int dim = parseArrayDimension();            return new Declarator(t, dim);        }        else {            ASTList name = parseClassType(tbl);            int dim = parseArrayDimension();            return new Declarator(name, dim);        }    }    private static boolean isBuiltinType(int t) {        return (t == BOOLEAN || t == BYTE || t == CHAR || t == SHORT                || t == INT || t == LONG || t == FLOAT || t == DOUBLE);    }    /* formal.parameter : formal.type Identifier array.dimension     */    private Declarator parseFormalParam(SymbolTable tbl)        throws CompileError    {        Declarator d = parseFormalType(tbl);        if (lex.get() != Identifier)            throw new SyntaxError(lex);        String name = lex.getString();        d.setVariable(new Symbol(name));        d.addArrayDim(parseArrayDimension());        tbl.append(name, d);        return d;    }    /* statement : [ label ":" ]* labeled.statement     *     * labeled.statement     *          : block.statement     *          | if.statement     *          | while.statement     *          | do.statement     *          | for.statement     *          | switch.statement     *          | try.statement     *          | return.statement     *          | thorw.statement     *          | break.statement     *          | continue.statement     *          | declaration.or.expression     *          | ";"     *     * This method may return null (empty statement).     */    public Stmnt parseStatement(SymbolTable tbl)        throws CompileError    {        int t = lex.lookAhead();        if (t == '{')            return parseBlock(tbl);        else if (t == ';') {            lex.get();            return new Stmnt(BLOCK);    // empty statement        }        else if (t == Identifier && lex.lookAhead(1) == ':') {            lex.get();  // Identifier            String label = lex.getString();            lex.get();  // ':'            return Stmnt.make(LABEL, new Symbol(label), parseStatement(tbl));        }        else if (t == IF)            return parseIf(tbl);        else if (t == WHILE)            return parseWhile(tbl);        else if (t == DO)            return parseDo(tbl);        else if (t == FOR)            return parseFor(tbl);        else if (t == TRY)            return parseTry(tbl);        else if (t == SWITCH)            return parseSwitch(tbl);        else if (t == SYNCHRONIZED)            return parseSynchronized(tbl);        else if (t == RETURN)            return parseReturn(tbl);        else if (t == THROW)            return parseThrow(tbl);        else if (t == BREAK)            return parseBreak(tbl);        else if (t == CONTINUE)            return parseContinue(tbl);        else            return parseDeclarationOrExpression(tbl, false);    }    /* block.statement : "{" statement* "}"     */    private Stmnt parseBlock(SymbolTable tbl) throws CompileError {        if (lex.get() != '{')            throw new SyntaxError(lex);        Stmnt body = null;        SymbolTable tbl2 = new SymbolTable(tbl);        while (lex.lookAhead() != '}') {            Stmnt s = parseStatement(tbl2);            if (s != null)                body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s));        }        lex.get();      // '}'        if (body == null)            return new Stmnt(BLOCK);    // empty block        else            return body;    }    /* if.statement : IF "(" expression ")" statement     *                [ ELSE statement ]     */    private Stmnt parseIf(SymbolTable tbl) throws CompileError {        int t = lex.get();      // IF        ASTree expr = parseParExpression(tbl);        Stmnt thenp = parseStatement(tbl);        Stmnt elsep;        if (lex.lookAhead() == ELSE) {            lex.get();            elsep = parseStatement(tbl);        }        else            elsep = null;        return new Stmnt(t, expr, new ASTList(thenp, new ASTList(elsep)));    }    /* while.statement : WHILE "(" expression ")" statement     */    private Stmnt parseWhile(SymbolTable tbl)        throws CompileError    {        int t = lex.get();      // WHILE        ASTree expr = parseParExpression(tbl);        Stmnt body = parseStatement(tbl);        return new Stmnt(t, expr, body);    }    /* do.statement : DO statement WHILE "(" expression ")" ";"     */    private Stmnt parseDo(SymbolTable tbl) throws CompileError {        int t = lex.get();      // DO        Stmnt body = parseStatement(tbl);        if (lex.get() != WHILE || lex.get() != '(')            throw new SyntaxError(lex);        ASTree expr = parseExpression(tbl);        if (lex.get() != ')' || lex.get() != ';')            throw new SyntaxError(lex);        return new Stmnt(t, expr, body);    }    /* for.statement : FOR "(" decl.or.expr expression ";" expression ")"     *                 statement     */    private Stmnt parseFor(SymbolTable tbl) throws CompileError {        Stmnt expr1, expr3;        ASTree expr2;        int t = lex.get();      // FOR        SymbolTable tbl2 = new SymbolTable(tbl);        if (lex.get() != '(')            throw new SyntaxError(lex);        if (lex.lookAhead() == ';') {            lex.get();            expr1 = null;        }        else            expr1 = parseDeclarationOrExpression(tbl2, true);        if (lex.lookAhead() == ';')            expr2 = null;        else            expr2 = parseExpression(tbl2);        if (lex.get() != ';')            throw new CompileError("; is missing", lex);        if (lex.lookAhead() == ')')            expr3 = null;        else            expr3 = parseExprList(tbl2);        if (lex.get() != ')')            throw new CompileError(") is missing", lex);        Stmnt body = parseStatement(tbl2);        return new Stmnt(t, expr1, new ASTList(expr2,                                               new ASTList(expr3, body)));    }    /* switch.statement : SWITCH "(" expression ")" "{" switch.block "}"     *     * swtich.block : ( switch.label statement* )*     *     * swtich.label : DEFAULT ":"     *              | CASE const.expression ":"     */    private Stmnt parseSwitch(SymbolTable tbl) throws CompileError {        int t = lex.get();	// SWITCH        ASTree expr = parseParExpression(tbl);        Stmnt body = parseSwitchBlock(tbl);        return new Stmnt(t, expr, body);    }    private Stmnt parseSwitchBlock(SymbolTable tbl) throws CompileError {        if (lex.get() != '{')            throw new SyntaxError(lex);        SymbolTable tbl2 = new SymbolTable(tbl);        Stmnt s = parseStmntOrCase(tbl2);        if (s == null)            throw new CompileError("empty switch block", lex);        int op = s.getOperator();        if (op != CASE && op != DEFAULT)            throw new CompileError("no case or default in a switch block",                                   lex);        Stmnt body = new Stmnt(BLOCK, s);        while (lex.lookAhead() != '}') {            Stmnt s2 = parseStmntOrCase(tbl2);            if (s2 != null) {                int op2 = s2.getOperator();                if (op2 == CASE || op2 == DEFAULT) {                    body = (Stmnt)ASTList.concat(body, new Stmnt(BLOCK, s2));                    s = s2;                }                else                    s = (Stmnt)ASTList.concat(s, new Stmnt(BLOCK, s2));            }        }        lex.get();      // '}'        return body;    }    private Stmnt parseStmntOrCase(SymbolTable tbl) throws CompileError {        int t = lex.lookAhead();        if (t != CASE && t != DEFAULT)            return parseStatement(tbl);        lex.get();        Stmnt s;        if (t == CASE)            s = new Stmnt(t, parseExpression(tbl));        else            s = new Stmnt(DEFAULT);        if (lex.get() != ':')            throw new CompileError(": is missing", lex);        return s;    }

⌨️ 快捷键说明

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