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

📄 parser.java

📁 javac是sun公司开发人员使用java语言编写的优秀的工业级java编译器
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/** * @(#)Parser.java	1.39 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.tools.javac.v8.parser;import com.sun.tools.javac.v8.tree.*;import com.sun.tools.javac.v8.code.*;import com.sun.tools.javac.v8.util.*;import com.sun.tools.javac.v8.tree.Tree.*;/** * The parser maps a token sequence into an abstract syntax *  tree. It operates by recursive descent, with code derived *  systematically from an LL(1) grammar. For efficiency reasons, an *  operator precedence scheme is used for parsing binary operation *  expressions. */public class Parser implements Tokens {    /**     * The number of precedence levels of infix operators.     */    private static final int infixPrecedenceLevels = 10;    /**     * The scanner used for lexical analysis.     */    private Scanner S;    /**     * The factory to be used for abstract syntax tree construction.     */    private TreeMaker F;    /**     * The log to be used for error diagnostics.     */    private Log log;    /**     * The keyword table.     */    private Keywords keywords;    /**     * The Source language setting.     */    private Source source;    /**     * The name table.     */    private Name.Table names;    /**     * Construct a parser from a given scanner, tree factory and log.     *  @param genEndPos Should endPositions be generated?     */    public Parser(Context context, Scanner S, boolean keepDocComments,            boolean genEndPos) {        super();        this.S = S;        this.F = TreeMaker.instance(context);        this.log = Log.instance(context);        this.names = Name.Table.instance(context);        this.keywords = Keywords.instance(context);        this.keepDocComments = keepDocComments;        this.source = Source.instance(context);        this.allowAsserts = source.ordinal >= Source.JDK1_4.ordinal;        this.genEndPos = genEndPos;        if (keepDocComments)            docComments = new Hashtable();        if (genEndPos)            endPositions = new Hashtable();    }    /**      * Switch: should we keep docComments?      */    boolean keepDocComments;    /**     * Switch: should we recognize assert statements, or just give a warning?     */    boolean allowAsserts;    /**     * Switch: should we store the ending positions?     */    boolean genEndPos;    /**     * When terms are parsed, the mode determines which is expected:     *     mode = EXPR        : an expression     *     mode = TYPE        : a type     *     mode = NOPARAMS    : no parameters allowed for type     */    static final int EXPR = 1;    static final int TYPE = 2;    static final int NOPARAMS = 4;    /**     * The current mode.     */    private int mode = 0;    /**     * The mode of the term that was parsed last.     */    private int lastmode = 0;    static Tree errorTree = new Tree.Erroneous();    /**     * Skip forward until a suitable stop token is found.     */    private void skip() {        int nbraces = 0;        int nparens = 0;        while (true) {            switch (S.token) {            case EOF:            case CLASS:            case INTERFACE:                return;            case SEMI:                if (nbraces == 0 && nparens == 0)                    return;                break;            case RBRACE:                if (nbraces == 0)                    return;                nbraces--;                break;            case RPAREN:                if (nparens > 0)                    nparens--;                break;            case LBRACE:                nbraces++;                break;            case LPAREN:                nparens++;                break;            default:            }            S.nextToken();        }    }    /**      * Generate a syntax error at given position using the given argument      *  unless one was already reported at the same position, then skip.      */    private Tree syntaxError(int pos, String key, String arg) {        if (pos != S.errPos)            log.error(pos, key, arg);        skip();        S.errPos = pos;        return errorTree;    }    /**      * Generate a syntax error at given position unless one was already      *  reported at the same position, then skip.      */    private Tree syntaxError(int pos, String key) {        return syntaxError(pos, key, null);    }    /**      * Generate a syntax error at current position unless one was already reported      *  at the same position, then skip.      */    private Tree syntaxError(String key) {        return syntaxError(S.pos, key, null);    }    /**      * Generate a syntax error at current position unless one was already reported      *  at the same position, then skip.      */    private Tree syntaxError(String key, String arg) {        return syntaxError(S.pos, key, arg);    }    /**      * If next input token matches given token, skip it, otherwise report an error.      */    private void accept(int token) {        if (S.token == token) {            S.nextToken();        } else {            int pos = Position.line(S.pos) > Position.line(S.prevEndPos + 1) ?                    S.prevEndPos + 1 : S.pos;            syntaxError(pos, "expected", keywords.token2string(token));            if (S.token == token)                S.nextToken();        }    }    /**      * Report an illegal start of expression/type error at given position.      */    Tree illegal(int pos) {        if ((mode & EXPR) != 0)            return syntaxError(pos, "illegal.start.of.expr");        else            return syntaxError(pos, "illegal.start.of.type");    }    /**      * Report an illegal start of expression/type error at current position.      */    Tree illegal() {        return illegal(S.pos);    }    /**      * A hashtable to store all documentation comments      *  indexed by the tree nodes they refer to.      *  defined only if option flag keepDocComment is set.      */    Hashtable docComments;    /**     * Make an entry into docComments hashtable,     *  provided flag keepDocComments is set and given doc comment is non-null.     *  @param tree   The tree to be used as index in the hashtable     *  @param dc     The doc comment to associate with the tree, or null.     */    void attach(Tree tree, String dc) {        if (keepDocComments && dc != null) {            docComments.put(tree, dc);        }    }    /**      * A hashtable to store ending positions      *  of source ranges indexed by the tree nodes.      *  Defined only if option flag genEndPos is set.      */    Hashtable endPositions;    /**     * Make an entry into endPositions hashtable, provided flag     *  genEndPos is set. Note that this method is usually hand-inlined.     *  @param tree   The tree to be used as index in the hashtable     *  @param endPos The ending position to associate with the tree.     */    void storeEnd(Tree tree, int endpos) {        if (genEndPos)            endPositions.put(tree, new Integer(endpos));    }    /**      * Ident = IDENTIFIER      */    Name ident() {        if (S.token == IDENTIFIER) {            Name name = S.name;            S.nextToken();            return name;        }        if (S.token == ASSERT) {            if (allowAsserts) {                log.error(S.pos, "assert.as.identifier");                S.nextToken();                return names.error;            } else {                log.warning(S.pos, "assert.as.identifier");                Name name = S.name;                S.nextToken();                return name;            }        } else {            accept(IDENTIFIER);            return names.error;        }    }    /**      * Qualident = Ident { DOT Ident }      */    Tree qualident() {        Tree t = F.at(S.pos).Ident(ident());        while (S.token == DOT) {            int pos = S.pos;            S.nextToken();            t = F.at(pos).Select(t, ident());        }        return t;    }    /**      * Literal =      *	   INTLITERAL      *	 | LONGLITERAL      *	 | FLOATLITERAL      *	 | DOUBLELITERAL      *	 | CHARLITERAL      *	 | STRINGLITERAL      *       | TRUE      *       | FALSE      *       | NULL      */    Tree literal(Name prefix) {        int pos = S.pos;        Tree t = errorTree;        switch (S.token) {        case INTLITERAL:            try {                t = F.at(pos).Literal(Type.INT,                        new Integer(Convert.string2int(strval(prefix), S.radix)));            } catch (NumberFormatException ex) {                log.error(S.pos, "int.number.too.large", strval(prefix));            }            break;        case LONGLITERAL:            try {                t = F.at(pos).Literal(Type.LONG,                        new Long(Convert.string2long(strval(prefix), S.radix)));            } catch (NumberFormatException ex) {                log.error(S.pos, "int.number.too.large", strval(prefix));            }            break;        case FLOATLITERAL:            {                Float n = Float.valueOf(S.stringVal());                if (n.floatValue() == 0.0F && !isZero(S.stringVal()))                    log.error(S.pos, "fp.number.too.small");                else if (n.floatValue() == Float.POSITIVE_INFINITY)                    log.error(S.pos, "fp.number.too.large");                else                    t = F.at(pos).Literal(Type.FLOAT, n);                break;            }        case DOUBLELITERAL:            {                Double n = Double.valueOf(S.stringVal());                if (n.doubleValue() == 0.0 && !isZero(S.stringVal()))                    log.error(S.pos, "fp.number.too.small");                else if (n.doubleValue() == Double.POSITIVE_INFINITY)                    log.error(S.pos, "fp.number.too.large");                else                    t = F.at(pos).Literal(Type.DOUBLE, n);                break;            }        case CHARLITERAL:            t = F.at(pos).Literal(Type.CHAR, new Integer(S.stringVal().charAt(0)));            break;        case STRINGLITERAL:            t = F.at(pos).Literal(Type.CLASS, S.stringVal());            break;        case TRUE:        case FALSE:        case NULL:            t = F.at(pos).Ident(S.name);            break;        default:            assert false;        }        S.nextToken();        return t;    }    boolean isZero(String s) {        char[] cs = s.toCharArray();        int i = 0;        while (i < cs.length && (cs[i] == '0' || cs[i] == '.'))            i++;        return !(i < cs.length && ('1' <= cs[i] && cs[i] <= '9'));    }    String strval(Name prefix) {        String s = S.stringVal();        return (prefix.len == 0) ? s : prefix + s;    }    /**      * terms can be either expressions or types.      */    Tree expression() {        return term(EXPR);    }    Tree type() {        return term(TYPE);    }    Tree term(int newmode) {        int prevmode = mode;        mode = newmode;        Tree t = term();        lastmode = mode;        mode = prevmode;        return t;    }    /**      *  Expression = Expression1 [ExpressionRest]      *  ExpressionRest = [AssignmentOperator Expression1]      *  AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" |  "&=" | "|=" | "^=" |      *                       "%=" | "<<=" | ">>=" | ">>>="      *  Type = Type1      *  TypeNoParams = TypeNoParams1      *  StatementExpression = Expression      *  ConstantExpression = Expression      */    Tree term() {        Tree t = term1();        if ((mode & EXPR) != 0 && S.token == EQ || PLUSEQ <= S.token &&                S.token <= GTGTGTEQ)            return termRest(t);        else            return t;    }    Tree termRest(Tree t) {        switch (S.token) {        case EQ:            {                int pos = S.pos;                S.nextToken();                mode = EXPR;                Tree t1 = term();                return F.at(pos).Assign(t, t1);            }        case PLUSEQ:        case SUBEQ:        case STAREQ:        case SLASHEQ:        case PERCENTEQ:

⌨️ 快捷键说明

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