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

📄 parser.java

📁 是一款用JAVA 编写的编译器 具有很强的编译功能
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */package com.sun.tools.javac.parser;import java.util.*;import com.sun.tools.javac.tree.*;import com.sun.tools.javac.code.*;import com.sun.tools.javac.util.*;import com.sun.tools.javac.util.List;import static com.sun.tools.javac.util.ListBuffer.lb;import com.sun.tools.javac.tree.JCTree.*;import static com.sun.tools.javac.parser.Token.*;/** 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. * *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If *  you write code that depends on this, you do so at your own risk. *  This code and its internal interfaces are subject to change or *  deletion without notice.</b> */public class Parser {    /** A factory for creating parsers. */    public static class Factory {        /** The context key for the parser factory. */        protected static final Context.Key<Parser.Factory> parserFactoryKey =            new Context.Key<Parser.Factory>();        /** Get the Factory instance for this context. */        public static Factory instance(Context context) {            Factory instance = context.get(parserFactoryKey);            if (instance == null)                instance = new Factory(context);            return instance;        }        final TreeMaker F;        final Log log;        final Keywords keywords;        final Source source;        final Name.Table names;        final Options options;        /** Create a new parser factory. */        protected Factory(Context context) {            context.put(parserFactoryKey, this);            this.F = TreeMaker.instance(context);            this.log = Log.instance(context);            this.names = Name.Table.instance(context);            this.keywords = Keywords.instance(context);            this.source = Source.instance(context);            this.options = Options.instance(context);        }        /**         * Create a new Parser.         * @param S Lexer for getting tokens while parsing         * @param keepDocComments true if javadoc comments should be kept         * @param genEndPos true if end positions should be generated         */        public Parser newParser(Lexer S, boolean keepDocComments, boolean genEndPos) {            if (!genEndPos)                return new Parser(this, S, keepDocComments);            else                return new EndPosParser(this, S, keepDocComments);        }    }    /** The number of precedence levels of infix operators.     */    private static final int infixPrecedenceLevels = 10;    /** The scanner used for lexical analysis.     */    private Lexer S;    /** The factory to be used for abstract syntax tree construction.     */    protected 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.     */    protected Parser(Factory fac,                     Lexer S,                     boolean keepDocComments) {        this.S = S;        S.nextToken(); // prime the pump        this.F = fac.F;        this.log = fac.log;        this.names = fac.names;        this.keywords = fac.keywords;        this.source = fac.source;        Options options = fac.options;        this.allowGenerics = source.allowGenerics();        this.allowVarargs = source.allowVarargs();        this.allowAsserts = source.allowAsserts();        this.allowEnums = source.allowEnums();        this.allowForeach = source.allowForeach();        this.allowStaticImport = source.allowStaticImport();        this.allowAnnotations = source.allowAnnotations();        this.keepDocComments = keepDocComments;        if (keepDocComments) docComments = new HashMap<JCTree,String>();        this.errorTree = F.Erroneous();    }    /** Switch: Should generics be recognized?     */    boolean allowGenerics;    /** Switch: Should varargs be recognized?     */    boolean allowVarargs;    /** Switch: should we recognize assert statements, or just give a warning?     */    boolean allowAsserts;    /** Switch: should we recognize enums, or just give a warning?     */    boolean allowEnums;    /** Switch: should we recognize foreach?     */    boolean allowForeach;    /** Switch: should we recognize foreach?     */    boolean allowStaticImport;    /** Switch: should we recognize annotations?     */    boolean allowAnnotations;    /** Switch: should we keep docComments?     */    boolean keepDocComments;    /** 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     *     mode = TYPEARG     : type argument     */    static final int EXPR = 1;    static final int TYPE = 2;    static final int NOPARAMS = 4;    static final int TYPEARG = 8;    /** The current mode.     */    private int mode = 0;    /** The mode of the term that was parsed last.     */    private int lastmode = 0;/* ---------- error recovery -------------- */    private JCErroneous errorTree;    /** Skip forward until a suitable stop token is found.     */    private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {         while (true) {             switch (S.token()) {                case SEMI:                    S.nextToken();                    return;                case PUBLIC:                case FINAL:                case ABSTRACT:                case MONKEYS_AT:                case EOF:                case CLASS:                case INTERFACE:                case ENUM:                    return;                case IMPORT:                    if (stopAtImport)                        return;                    break;                case LBRACE:                case RBRACE:                case PRIVATE:                case PROTECTED:                case STATIC:                case TRANSIENT:                case NATIVE:                case VOLATILE:                case SYNCHRONIZED:                case STRICTFP:                case LT:                case BYTE:                case SHORT:                case CHAR:                case INT:                case LONG:                case FLOAT:                case DOUBLE:                case BOOLEAN:                case VOID:                    if (stopAtMemberDecl)                        return;                    break;                case IDENTIFIER:                   if (stopAtIdentifier)                        return;                    break;                case CASE:                case DEFAULT:                case IF:                case FOR:                case WHILE:                case DO:                case TRY:                case SWITCH:                case RETURN:                case THROW:                case BREAK:                case CONTINUE:                case ELSE:                case FINALLY:                case CATCH:                    if (stopAtStatement)                        return;                    break;            }            S.nextToken();        }    }    private JCErroneous syntaxError(int pos, String key, Object... arg) {        return syntaxError(pos, null, key, arg);    }    private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Object... arg) {        setErrorEndPos(pos);        reportSyntaxError(pos, key, arg);        return toP(F.at(pos).Erroneous(errs));    }    private int errorPos = Position.NOPOS;    /**     * Report a syntax error at given position using the given     * argument unless one was already reported at the same position.     */    private void reportSyntaxError(int pos, String key, Object... arg) {        if (pos > S.errPos() || pos == Position.NOPOS) {            if (S.token() == EOF)                log.error(pos, "premature.eof");            else                log.error(pos, key, arg);        }        S.errPos(pos);        if (S.pos() == errorPos)            S.nextToken(); // guarantee progress        errorPos = S.pos();    }    /** Generate a syntax error at current position unless one was already     *  reported at the same position.     */    private JCErroneous syntaxError(String key) {        return syntaxError(S.pos(), key);    }    /** Generate a syntax error at current position unless one was     *  already reported at the same position.     */    private JCErroneous syntaxError(String key, String arg) {        return syntaxError(S.pos(), key, arg);    }    /** If next input token matches given token, skip it, otherwise report     *  an error.     */    public void accept(Token token) {        if (S.token() == token) {            S.nextToken();        } else {            setErrorEndPos(S.pos());            reportSyntaxError(S.prevEndPos(), "expected", keywords.token2string(token));        }    }    /** Report an illegal start of expression/type error at given position.     */    JCExpression illegal(int pos) {        setErrorEndPos(S.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.     */    JCExpression illegal() {        return illegal(S.pos());    }    /** Diagnose a modifier flag from the set, if any. */    void checkNoMods(long mods) {        if (mods != 0) {            long lowestMod = mods & -mods;            log.error(S.pos(), "mod.not.allowed.here",                      Flags.toString(lowestMod).trim());        }    }/* ---------- doc comments --------- */    /** A hashtable to store all documentation comments     *  indexed by the tree nodes they refer to.     *  defined only if option flag keepDocComment is set.     */    Map<JCTree, String> 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.

⌨️ 快捷键说明

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