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 + -
显示快捷键?