scriptparser.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 815 行 · 第 1/2 页

JAVA
815
字号
/* *    * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program 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. *  * This program 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 at /legal/license.txt). *  * 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 or visit www.sun.com if you need additional * information or have any questions. */package com.sun.midp.automation.example.scripting;import java.io.InputStream;import java.util.Hashtable;import java.util.Vector;import java.util.Enumeration;class Scope {    Hashtable identifiers;    Scope outer;    Scope(Scope outer) {        this.outer = outer;        this.identifiers = new Hashtable();    }}class ScriptParser {    private InputStream input;    private int lineNumber;    private int nextChar, nextNextChar;    private Scope scope;    private final static int DEFINITION_VAR     = 0;    private final static int DEFINITION_CONST   = 1;    private final static int DEFINITION_STATIC = 2;    static Script parse(InputStream input, ScriptExtension plugin) {        ScriptParser parser = new ScriptParser(input);        if (plugin != null) {            ExternalCall.plugin = plugin;            plugin.register(parser);        }        return parser.readScript();    }    void registerExternalVariable(String name, Variable var) {        registerIdentifier(name, var);    }    void registerExternalConstant(String name, Constant c) {        registerIdentifier(name, c);    }    void registerExternalFunction(String name, int function) {        registerIdentifier(name, new Integer(function));    }    void registerExternalFunctions(String[] names) {        if (names != null) {            for (int i = 0; i < names.length; i++) {                registerExternalFunction(names[i], i);            }        }    }    ScriptParser(InputStream input) {        this.input = input;        lineNumber = 1;        nextChar = nextNextChar = 0;        scope = new Scope(null);        registerIdentifier(ArrayFactory.CONSTRUCTOR_NAME, new ArrayFactory());    }    void emitError(String message) {        throw new RuntimeException(message + " at line " + lineNumber);    }    void emitWarning(String message) {        System.out.println("Warning: " + message + " at line " + lineNumber);    }    Script readScript() {        Script script = new Script();        registerIdentifier(Variable.RETURN_NAME, script.locals[0]);        script.entry = readSequence();        skipSpaces();        if (nextChar != -1) {            emitWarning("Symbols beyond end of script");        }        return script;    }    Instruction readSequence() {        Instruction first = readInstruction();        Instruction current = first;        while (current != null) {            current = tie(current, readInstruction());        }        return first;    }    Instruction readInstruction() {        String name;        boolean extern = false;                while (true) {            skipSpaces();            if (nextChar == '}' || nextChar == -1) {                return null;            }            if (nextChar == ';') {                readChar();                return new Instruction();            }            if (nextChar == '{') {                readChar();                Instruction instr = readSequence();                requireChar('}');                return instr;            }            name = readIdentifier();            if (name.equals("var")) {                Instruction instr = readVariables(DEFINITION_VAR, extern);                if (instr != null) {                    return instr;                }                continue;            } else if (name.equals("const")) {                readVariables(DEFINITION_CONST, extern);                continue;            } else if (name.equals("static")) {                readVariables(DEFINITION_STATIC, extern);                continue;            } else if (name.equals("function")) {                readFunction(extern);                continue;            } else if (name.equals("extern")) {                extern = true;                continue;            } else if (name.equals("goto")) {                return readGoto();            } else if (name.equals("return")) {                return readReturn();            } else if (name.equals("if")) {                return readIf();            } else if (name.equals("while")) {                return readWhile();            } else if (name.equals("do")) {                return readDo();            } else if (name.equals("for")) {                return readFor();            }            skipSpaces();            if (nextChar == ':') {                readChar();                return setLabel(name);            }            if (nextChar == '(') {                return readCall(name, true);            }            return readAssignment(name, true);        }    }    Instruction readVariables(int deftype, boolean extern) {        Instruction instr = null;        do {            if (instr == null) {                instr = readVariable(deftype, extern);            } else {                tie(instr, readVariable(deftype, extern));            }            skipSpaces();        } while (nextChar != ';' && readChar() == ',');        requireChar(';');        return instr;    }    Instruction readVariable(int deftype, boolean extern) {        String name = readIdentifier();        Expression init;                skipSpaces();        if (nextChar == '=') {            readChar();            init = readExpression();        } else {            init = Constant.NULL;        }        if (extern && findIdentifier(name, true) != null) {                return null;        }        switch (deftype) {        case DEFINITION_VAR:            Variable var = new Variable();            registerIdentifier(name, var);            return init == Constant.NULL ? null : new Assignment(var, init);        case DEFINITION_CONST:            if (!(init instanceof Constant)) {                emitError("Constant expression needed");            }            registerIdentifier(name, init);            break;        case DEFINITION_STATIC:            Constant c = init.evaluate();            if (c == Constant.NULL) {                c = new Constant();            }            registerIdentifier(name, new Variable(c));            break;        }        return null;    }    void readFunction(boolean extern) {        String name = readIdentifier();        Object id = findIdentifier(name, false);        Routine subroutine;        if (id instanceof Integer) {            if (!extern) {                emitWarning("External function with the same name (" +                         name + ") registred");            }            subroutine = new Routine();        } else if (id instanceof Routine) {            subroutine = (Routine)id;            if (subroutine.entry != null && !isNop(subroutine.entry)) {                emitWarning("Redifinition of function " + name);            }        } else {            registerIdentifier(name, subroutine = new Routine());        }        scope = new Scope(scope);        Vector locals = new Vector();        Variable var;        requireChar('(');        skipSpaces();        if (nextChar != ')') {            do {                registerIdentifier(readIdentifier(), var = new Variable());                locals.addElement(var);                skipSpaces();            } while (nextChar != ')' && readChar() == ',');        }        requireChar(')');        registerIdentifier(Variable.RETURN_NAME, var = new Variable());        subroutine.entry = readInstruction();        subroutine.args = locals.size();        locals.addElement(var);        for (Enumeration e = scope.identifiers.elements(); e.hasMoreElements(); ) {            id = e.nextElement();            if (id instanceof Variable && ((Variable)id).value == Constant.NULL) {                locals.addElement(id);            }        }                subroutine.locals = new Variable[locals.size()];        locals.copyInto(subroutine.locals);        scope = scope.outer;    }    Instruction setLabel(String name) {        Instruction target = readInstruction();        if (target == null) {            emitError("Cannot set label here");        }        Object id = findIdentifier(name, false);        if (id == null || !(id instanceof Instruction)) {            registerIdentifier(name, target);            return target;        }        Instruction dummy = (Instruction)id;        if (!isNop(dummy)) {            emitError("Label already set");        }        dummy.next = target;        return dummy;    }    Call readCall(String name, boolean statement) {        Expression params[] = readParams();        if (statement) {            requireChar(';');        }        Object id = findIdentifier(name, true);        if (id instanceof Integer) {            return new ExternalCall(((Integer)id).intValue(), params);        } else if (id instanceof Routine) {            return new SubroutineCall((Routine)id, params);        } else {            emitError("Unknown function " + name);            return null;        }    }    Expression[] readParams() {        requireChar('(');        skipSpaces();        if (nextChar == ')') {            readChar();            return null;        }                Vector parameters = new Vector();        do {            parameters.addElement(readExpression());            skipSpaces();        } while (nextChar != ')' && readChar() == ',');        requireChar(')');        Expression params[] = new Expression[parameters.size()];        parameters.copyInto(params);        return params;    }    Instruction readAssignment(String name, boolean statement) {        Expression var = readLvalue(name);        if (var instanceof Constant) {            emitError("Assignment to a constant");        }        Expression expr;        if (nextChar == '=') {            readChar();            expr = readExpression();            if (statement) {                requireChar(';');            }            return new Assignment(var, expr);        }        int operation;        boolean unary = true;        if ((operation = testOperator('+', '+', Compound.OPERATOR_ADD)) == 0)        if ((operation = testOperator('-', '-', Compound.OPERATOR_SUB)) == 0) {            unary = false;            if ((operation = testOperator('+', '=', Compound.OPERATOR_ADD)) == 0)            if ((operation = testOperator('-', '=', Compound.OPERATOR_SUB)) == 0)            if ((operation = testOperator('*', '=', Compound.OPERATOR_MUL)) == 0)            if ((operation = testOperator('/', '=', Compound.OPERATOR_DIV)) == 0)            if ((operation = testOperator('%', '=', Compound.OPERATOR_REM)) == 0)            if ((operation = testOperator('&', '=', Compound.OPERATOR_BITWISE_AND)) == 0)            if ((operation = testOperator('|', '=', Compound.OPERATOR_BITWISE_OR)) == 0) {                if ((operation = testOperator('<', '<', Compound.OPERATOR_SHL)) == 0)                if ((operation = testOperator('>', '>', Compound.OPERATOR_SHR)) == 0) {                    emitError("Illegal instruction");                }                requireChar('=');            }        }        expr = unary ? Constant.ONE : readExpression();        if (statement) {            requireChar(';');        }        return new Assignment(var, buildExpression(operation, var, expr));    }    Instruction readGoto() {        String name = readIdentifier();        Instruction target = (Instruction)findIdentifier(name, false);        if (target == null) {            registerIdentifier(name, target = new Instruction());        }        requireChar(';');        return new Branch(Constant.TRUE, target);    }    Instruction readReturn() {        skipSpaces();        if (nextChar == ';') {            readChar();            return new Branch(Constant.TRUE, null);        }        Variable var = (Variable)findIdentifier(Variable.RETURN_NAME, false);        if (var == null) {            emitError("Routine is not expected to return a value");        }        Instruction instr = new Assignment(var, readExpression());        instr.next = new Branch(Constant.TRUE, null);        requireChar(';');        return instr;    }

⌨️ 快捷键说明

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