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

📄 parser.java

📁 一个非常简洁的java脚本引擎
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
package murlen.util.fscript;import java.io.*;import java.util.HashMap;import java.util.ArrayList;/** * <b>Parser - Does the parsing - i.e it's the brains of the code.</b> * <p> * <I>Copyright (C) 2000-2003 murlen.</I></p> * <p> * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version.</p> * <p> * This library 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 * Library General Public License for more details.</p> * * <p>You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA </p> * @author murlen * @author Joachim Van der Auwera * @version 1.12 * * modifications by Joachim Van der Auwera * 14.08.2001 added support for indexed variables * 20.08.2001 -clean handling of setVar with null value *   - cleaner handling of if with null condition *   - make sure running empty script does nothing *   - extra info when throwing an exception (with surrounding lines) *   - changed operator prioritues for && and || *   - fixed bug in parseIf with handling of nesting of if clauses with else *   - check for missing endif or endwhile (caused infinit loops) *   - check for a null to prevernt excepion in parseExpr * 28.08.2001 *   - call to host.getVar() replaced by host.F() (and added *     proper exception handling, in that case) * 31.08.2001 *   - test on if condition being of correct type re-introduced * 10.09.2001 *   - added < <= > >= on strings * 23.11.2001 *   - allow adding strings with anything * 04.12.2001 *   - allow add/subtract/multiply/divide int with double * 24.04.2002 *   - fixed a bug in parsing of nested if clause when one of the nested items contains a *     "then" token with the statements on the next line(s) (test for TT_EOL instead of TT_EOF) * 30.04.2002 *   - handle all exceptions on all getVarEntry, setVarEntry and callFunctionEntry calls * 06.05.2002 *   - error messages now unique *   - TT_EOF handled better in some cases * 05-06.08.2002 *   - removed some redundant code *   - introduced parseFunctionEnd to catch functions without return (it worked before, so...) * 21.10.2002 *   - added == for FSObject instances * 30.10.2002 object now allowed as function parameter * 07.11.2002 better error handling when parsing an expression * 20.11.2002 make != work for objects * 15.03.2003 getContext() added JVDA * 17.09.2003 removed checking for mismatched quotes and brackets, and moved to LineLoader * 23.11.2003 recycle LexAnn objects (saves object allocation/release) JVDA * 24.11.2003 some extra (smallish) speed improvements (also to reduce garbage a little bit) * 25.02.2004 * - proper evaluation of FSObject with contained boolean/integer for if/while * - more powerful compare for FSObject instance with something else * 14.04.2004 elsif opperator support */final class Parser {    public static final Integer FS_TRUE=new Integer(1);    public static final Integer FS_FALSE=new Integer(0);    //simple data class used internally to store function defs    class FuncEntry {        int startLine; //start line of function        int endLine; //end line of function        ArrayList paramNames; //list of parameter names        HashMap params; //hashmap of parameters        FuncEntry() {            startLine=0;            endLine=0;            paramNames=new ArrayList(4);            params=new HashMap();        }        public String toString() {            String s;            s=startLine + " " ;            s=s+endLine + " ";            s=s+paramNames + " ";            s=s+params;            return s;        }    }    //exception that occurs when someone calls return    class RetException extends Exception {}    private LineLoader code; //the code    private LexAnn tok; //tokenizer    private int maxLine;    private HashMap vars; //function local variables    private HashMap gVars; //global variables    private static HashMap opPrio; //operator priority table    private FScript host; //link to hosting FScript object    private HashMap funcs; //function map    private Object retVal; //return value    private Parser subParser;   //nested parser, for callback routines in FSParserExtension    private String error[];    /** Public constructor     * @param h a reference to the FScript object     */    Parser(FScript h) {        vars=new HashMap();        gVars=null;        funcs=new HashMap();        host=h;        setPrio();    }    //only used for function calls - note it is private    private Parser(FScript h,HashMap l,HashMap g, HashMap f) {        vars=l;        gVars=g;        funcs=f;        host=h;    }    /**     * Sets the LineLoader clas to be used for input     * @param in - the class     */    void setCode(LineLoader in) {        code=in;    }    /**     *The main parsing function     *@param from - the start line number     *@param to - the end line number     *returns an Object (currently a Integer or String) depending     *on the return value of the code parsed, or null if none.     */    Object parse(int from,int to) throws IOException, FSException {        // nothing to do when starting beond the code end        if (code.lineCount()<=from) return null;        maxLine=to;        code.setCurLine(from);        tok=new LexAnn(code.getLine());        getNextToken();        while (tok.ttype!=LexAnn.TT_EOF) {            //a script must always start with a word...            try {                parseStmt();            } catch (RetException e) {                return retVal;            }            getNextToken();        }        return null;    }    /**     * The main parsing function     * @param line - the line to be parsed     * @return an Object depending on the return value of the code parsed, or null if none.     */    Object parse(String line) throws IOException, FSException {        int oldLine=code.curLine;        try {            code.curLine=-1;            code.forError=line;            char[] chars=line.toCharArray();            LineLoader.checkLine(chars);            tok=new LexAnn(chars);            tok.nextToken();            // a script must always start with a word...            try {                parseStmt();            } catch (RetException e) {                return retVal;            }        } finally {            code.curLine=oldLine;        }        return null;    }    /**     * Resets the parser state.     */    void reset(){        if (vars!=null){            vars.clear();        }        if (gVars!=null){            gVars.clear();        }    }    //builds the operator priority table    private void setPrio(){        if (opPrio==null){            opPrio=new HashMap();            //from low to high            Integer prio;            prio=new Integer(1);            opPrio.put(new Integer(LexAnn.TT_LOR),prio);            prio=new Integer(2);            opPrio.put(new Integer(LexAnn.TT_LAND),prio);            prio=new Integer(5);            opPrio.put(new Integer(LexAnn.TT_LEQ),prio);            opPrio.put(new Integer(LexAnn.TT_LNEQ),prio);            opPrio.put(new Integer(LexAnn.TT_LGR),prio);            opPrio.put(new Integer(LexAnn.TT_LGRE),prio);            opPrio.put(new Integer(LexAnn.TT_LLS),prio);            opPrio.put(new Integer(LexAnn.TT_LLSE),prio);            prio=new Integer(10);            opPrio.put(new Integer(LexAnn.TT_PLUS),prio);            opPrio.put(new Integer(LexAnn.TT_MINUS),prio);            prio=new Integer(20);            opPrio.put(new Integer(LexAnn.TT_MULT),prio);            opPrio.put(new Integer(LexAnn.TT_DIV),prio);            opPrio.put(new Integer(LexAnn.TT_MOD),prio);        }    }    //statement - top level thing    private void parseStmt() throws IOException, FSException,RetException {        switch(tok.ttype) {            case LexAnn.TT_DEFINT:            case LexAnn.TT_DEFSTRING:            case LexAnn.TT_DEFDOUBLE:            case LexAnn.TT_DEFOBJECT: {                parseVarDef();                break;            }            case LexAnn.TT_IF: {                parseIf();                break;            }            case LexAnn.TT_WHILE: {                parseWhile();                break;            }            case LexAnn.TT_RETURN: {                parseReturn();                break;            }            case LexAnn.TT_DEFFUNC: {                parseFunctionDef();                break;            }            case LexAnn.TT_EDEFFUNC: {                parseFunctionEnd();                break;            }            case LexAnn.TT_EIF:                throw new FSException("unexpected endif");            case LexAnn.TT_EWHILE:                throw new FSException("unexpected endwhile");            case LexAnn.TT_FUNC: {                parseFunc();                break;            }            case LexAnn.TT_ARRAY: {                parseArrayAssign();                break;            }            case LexAnn.TT_WORD: {                parseAssign();                break;            }            case LexAnn.TT_EOL: {                tok.nextToken();                break;            }            case LexAnn.TT_EOF: {                // all done                break;            }            default: {                parseError("Expected identifier "+tok);            }        }    }    private void parseFunc() throws IOException,FSException {        String name;        name=(String)tok.value;        //should be a '('        getNextToken();        parseCallFunc(name);        getNextToken();    }    private void parseArrayAssign() throws IOException,FSException {        String name;        Object index;        Object val;        name=(String)tok.value;        getNextToken(); // should be a '['        getNextToken(); // should be the index        index=parseExpr();        getNextToken(); // should be a ']'        //getNextToken();        if (tok.ttype!=LexAnn.TT_EQ) {            parseError("Expected '='" );        } else {            getNextToken();            val=parseExpr();            try {                host.setVarEntry(name,index,val);            } catch (Exception e) {                parseError(e.getMessage());            }        }    }    //handles 'return' statements    private void parseReturn() throws IOException,FSException,RetException {        getNextToken();        retVal=parseExpr();        throw new RetException();    }    // handle endif without return, just return 1 (or true)    private void parseFunctionEnd() throws RetException {        retVal=FS_TRUE;        throw new RetException();    }    //Asignment parser    private void parseAssign() throws IOException, FSException {        String name;        Object val;        name=(String)tok.value;        getNextToken();        if (tok.ttype!=LexAnn.TT_EQ) {            parseError("Expected '='" );        } else {            getNextToken();            val=parseExpr();            if (hasVar(name)) {                setVar(name,val);            } else {                try {                    host.setVarEntry(name,null,val);                } catch (Exception e) {                    parseError(e.getMessage());                }            }        }    }    Object callFunction(String name,ArrayList params) throws    IOException,FSException{        FuncEntry fDef;        int n;

⌨️ 快捷键说明

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