package com.smtservlet.util; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SMTEvalString { public static void main1(String[] args) throws Exception { try { System.out.println(evalString("$v($strcmp(zbc,zbc, 0, 0),$strcmp(zbc,zbc, 0, 0))", new SMTEvalStringMethod(){ @Override public String onCallEvalMethod(EvalEnv env, String methodName, List listParam) { if(methodName.equals("a")) { System.out.println("call a"); return "$a$"; } if(methodName.equals("b")) { System.out.println("call b"); return "$b$"; } if(methodName.equals("v")) { for(int i = 0; i < listParam.size(); i ++) { SMTEvalString.getParam(env, listParam, i); } } return null; } }, null, null)); } catch(Exception ex) { ex.printStackTrace(); } } private static final char _EOF = 0xffff; private static final String _dateFmt = "yyyy-MM-dd HH:mm:ss"; public static class EvalEnv { private Object _methodLib; private Map _mapVarbs = null; private Object[] _argValues = null; private String[] _argNames = null; public EvalEnv(Object methodLib, Object[] argValues, String[] argNames) { _methodLib = methodLib; _argValues = argValues; _argNames = argNames; } public void setArgValue(String argName, String argValue) { if(this._argNames != null) { for(int i = 0; i < this._argNames.length; i ++) { if(argName.equalsIgnoreCase(this._argNames[i])) this._argValues[i] = argValue; } } } public void setVarbValue(String argName, String argValue) { if(this._mapVarbs == null) this._mapVarbs = new HashMap(); this._mapVarbs.put(argName, argValue); } public String getVarbValue(String argName, String defVal) { if(this._mapVarbs == null || !this._mapVarbs.containsKey(argName)) return defVal; return this._mapVarbs.get(argName); } public String callMethod(String methodName, List listParam)throws Exception { // 查询参数 if(this._argNames != null) { for(int i = 0; i < this._argNames.length; i ++) { if(methodName.equalsIgnoreCase(this._argNames[i])) return SMTEvalString.objectToString(this._argValues[i]); } } // 调用函数 String value = callMethod(this, _methodLib, methodName, listParam); if(value != null) return value; return null; } @SuppressWarnings("unchecked") private String callMethod(EvalEnv env, Object methodLib, String methodName, List listParam)throws Exception { if(methodLib == null) return null; else if(methodLib instanceof SMTEvalStringMethod) return ((SMTEvalStringMethod)methodLib).onCallEvalMethod(env, methodName, listParam); else if(methodLib instanceof List) { for(Object m : (List)methodLib) { if(m instanceof SMTEvalStringMethod) return ((SMTEvalStringMethod)methodLib).onCallEvalMethod(env, methodName, listParam); String value = callMethod(env, m, methodName, listParam); if(value != null) return value; } } else if(methodLib instanceof Object[]) { for(Object m : (Object[])methodLib) { if(m instanceof SMTEvalStringMethod) return ((SMTEvalStringMethod)methodLib).onCallEvalMethod(env, methodName, listParam); String value = callMethod(env, m, methodName, listParam); if(value != null) return value; } } else throw new RuntimeException(String.format("unsupport eval method type [%s]", methodLib.getClass().getName())); return null; } } public static class EvalNode { public String _methodName = null; public List _children = null; public void addChild(Object child) { if(_children == null) _children = new ArrayList(); _children.add(child); } public int childCount() { return _children == null ? 0 : _children.size(); } public String eval(EvalEnv env) { return (String)SMTEvalString.onCallMethod(env, _methodName, _children); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(String.format("$%s(", _methodName)); if(_children != null) { for(int i = 0; i < _children.size(); i ++) { sb.append((i > 0 ? ",[" : "[") + _children.get(i) + "]"); } } sb.append(")"); return sb.toString(); } } public static interface SMTEvalStringMethod { String onCallEvalMethod(EvalEnv env, String methodName, List listParam)throws Exception; } private static class CharIterator { protected String _str; protected int _pos; public CharIterator(String str) { _str = str; _pos = 0; } public boolean skipSpace() { if(_pos >= _str.length()) return false; for(; _pos < _str.length(); _pos ++) { char ch = _str.charAt(_pos); if(!(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')) return true; } return false; } public boolean skipToTail(int prevOffset, String tail) { if(_pos >= _str.length()) return false; int pos = _str.indexOf(tail, _pos); if(pos < 0) return false; _pos = pos + tail.length(); return true; } public char getChar(boolean moveNext) { if(_pos >= _str.length()) return _EOF; char ret = _str.charAt(_pos); if(moveNext) _pos ++; return ret; } public String getErrMsg(String msg) { return String.format("parse [%s] at pos [%d] error %s", _str, _pos, msg); } } public static String getParam(EvalEnv env, List listParam, int index, String defVal) { if(listParam == null || index >= listParam.size()) return defVal; Object param = listParam.get(index); if(param instanceof String) return (String)param; else if(param instanceof EvalNode) return ((EvalNode)param).eval(env); else throw new RuntimeException("param type error"); } public static String getParam(EvalEnv env, List listParam, int index) { String value = getParam(env, listParam, index, null); if(value == null) throw new RuntimeException(String.format("get eval param [%d] error", index)); return value; } public static String getNoEmptyParam(EvalEnv env, List listParam, int index) { String value = getParam(env, listParam, index, ""); if(value.length() == 0) throw new RuntimeException(String.format("get eval param [%d] error", index)); return value; } public static String getNoEmptyParam(EvalEnv env, List listParam, int index, String defVal) { String value = getParam(env, listParam, index, ""); if(value.length() == 0) return defVal; return value; } public static String evalString(String str, Object methodLib, Object[] args, String[] names) { EvalNode evalNode = evalNode(str); EvalEnv env = new EvalEnv(methodLib, args, names); return evalNode.eval(env); } public static EvalNode evalNode(String str) { CharIterator ci = new CharIterator(str); EvalNode evalNode = new EvalNode(); evalToChar(ci, evalNode, _EOF, _EOF, false, null); return evalNode; } protected static String evalToChar(CharIterator ci, EvalNode nodeParent, char endChar1, char endChar2, boolean addEmpty, char[] r_endChar) { EvalNode nodeParam = null; StringBuilder sbOut = new StringBuilder(); while(true) { // 获取下一个字符 char ch = ci.getChar(true); if(ch == '\r' || ch == '\n') continue; // 判断是否已经到了结尾 if(ch == endChar1 || ch == endChar2) { // 如果存在父节点,则处理 if(nodeParent != null) { // 如果没有插入过任何参数 if(nodeParam == null) { // 如果字符串不为空或者需要强制插入,则直接插入父节点 if(sbOut.length() > 0 || addEmpty) { nodeParent.addChild(sbOut.toString()); } } // 如果已经插入过参数了 else { // 如果字符串不为空,则插入参数节点,因为已经有参数了,因此为空的字符串不需要插入 if(sbOut.length() > 0 ) { EvalNode nodeParam1 = nodeParam; nodeParam = new EvalNode(); nodeParam.addChild(nodeParam1); nodeParam.addChild(sbOut.toString()); } // 将参数节点插入父节点 nodeParent.addChild(nodeParam); } } if(r_endChar != null) r_endChar[0] = ch; return sbOut.toString(); } if(ch == _EOF) throw new RuntimeException(ci.getErrMsg(String.format("can't find end char [%c,%c]", endChar1, endChar2))); if(ch == ')') throw new RuntimeException(ci.getErrMsg(String.format("find ')' no match"))); // 判断是否是转译字符 if(ch == '\\') { ch = ci.getChar(true); if(ch == _EOF) throw new RuntimeException(ci.getErrMsg(String.format("can't find end char [%c,%c]", endChar1, endChar2))); switch(ch) { case 'r':ch = '\r';break; case 'n':ch = '\n';break; case 't':ch = '\t';break; case 'b':ch = '\b';break; } sbOut.append(ch); } // 判断是否是函数调用或是注释($#xxxxx#$为注释) else if(ch == '$') { if(ci.getChar(false) == '{') { if(!ci.skipToTail(1, "}$")) throw new RuntimeException(ci.getErrMsg("can't find end comment")); } else { if(nodeParent == null) throw new RuntimeException("can't parse method calling in only"); // 首先将这之前解析的字符串保存到列表中 if(sbOut.length() > 0) { // 如果是第一次设置函数,则创建新的参数节点 if(nodeParam == null) { nodeParam = new EvalNode(); } // 如果已经是函数节点,则创建参数节点,并将函数节点作为参数节点的子节点 else if(nodeParam._methodName != null) { EvalNode tempNode = nodeParam; nodeParam = new EvalNode(); nodeParam.addChild(tempNode); } // 将字符串加入到参数节点中 nodeParam.addChild(sbOut.toString()); sbOut.setLength(0); } // 创建函数调用对象 EvalNode nodeMethod = new EvalNode(); evalToCallMethod(ci, nodeMethod); // 如果当前没有参数节点则假设只有一个函数调用 if(nodeParam == null) nodeParam = nodeMethod; // 如果当前已经有参数节点,则将其作为参数节点的子节点 else nodeParam.addChild(nodeMethod); } } // 其他字符则直接插入 else { sbOut.append(ch); } } } protected static void evalToCallMethod(CharIterator ci, EvalNode nodeMethod) { char[] endChars = new char[1]; // 获取函数名 String methodName = evalToChar(ci, null, '(', '$', false, endChars).toLowerCase().trim(); nodeMethod._methodName = methodName; // 如果格式为"$xxx("则表示需要分析参数(另一个格式为$xxxx$,则不需要分析参数) if(endChars[0] == '(') { for(int i = 0;; i ++) { evalToChar(ci, nodeMethod, ',', ')', i > 0, endChars); // 如果第一个参数的结尾是','则意味着有多个参数,因此需要插入第一个空参数 if(i == 0 && endChars[0] == ',' && nodeMethod.childCount() == 0) nodeMethod.addChild(""); else if(endChars[0] == ')') break; } } } public static String objectToString(Object value) { if(value == null) return ""; if(value instanceof Date) return new SimpleDateFormat(_dateFmt).format(value); else if((value instanceof Float) || (value instanceof Double)) { String ret = String.format("%f", value); if(ret.indexOf('.') > 0) { for(int i = ret.length() - 1; i >= 0; i --) { char ch = ret.charAt(i); if(ch == '.') { return ret.substring(0, i); } else if(ch != '0') return ret.substring(0, i + 1); } } return ret; } else return value.toString(); } protected static String trimString(String value) { int i = 0; for(; i < value.length(); i ++) { char ch = value.charAt(i); if(!(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')) break; } if(i > 0) { if(i == value.length()) return ""; value = value.substring(i); } for(i = value.length() - 1; i >= 0; i --) { char ch = value.charAt(i); if(!(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')) break; } if(i < (value.length() - 1)) value = value.substring(0, i + 1); return value; } protected static boolean objectBoolValue(Object value) { if(value == null) return false; if(value instanceof Boolean) return (Boolean)value; if(value instanceof String) { String svalue = trimString((String)value); return svalue.length() > 0 && !"0".equalsIgnoreCase(svalue) && !"false".equalsIgnoreCase(svalue); } if(value instanceof Integer) return ((Integer)value) != 0; if(value instanceof Long) return ((Long)value) != 0; if(value instanceof Float) return ((Float)value) != 0; if(value instanceof Double) return ((Double)value) != 0; return false; } protected static double parseDouble(String value) { return Double.parseDouble(trimString(value)); } protected static String onCallMethod(EvalEnv env, String methodName, List listParam) { try { // 调用匿名组合 if(methodName == null || methodName.length() == 0) { StringBuilder sb = new StringBuilder(); if(listParam != null) { for(Object node : listParam) { if(node instanceof String) sb.append((String)node); else if(node instanceof EvalNode) sb.append(((EvalNode)node).eval(env)); else throw new RuntimeException("unknow node type"); } } return sb.toString(); } // 调用外部函数 String value = env.callMethod(methodName, listParam); if(value != null) return value; // $join : 将字符串通过连接符连接成一个 // 参数1:连接符号 // 参数2-n : 要连接的字符串组 if("join".equalsIgnoreCase(methodName)) { String sp = SMTEvalString.getParam(env, listParam, 0); StringBuilder sb = new StringBuilder(); sb.append(SMTEvalString.getParam(env, listParam, 1)); for(int i = 2; i < listParam.size(); i ++) { sb.append(sp + SMTEvalString.getParam(env, listParam, i)); } return sb.toString(); } // $toLower : 字符串变小写 // 参数1 : 字符串 else if("lower".equalsIgnoreCase(methodName)) { return SMTEvalString.getParam(env, listParam, 0).toLowerCase(); } // $toUpper : 字符串变大写 // 参数1 : 字符串 else if("upper".equalsIgnoreCase(methodName)) { return SMTEvalString.getParam(env, listParam, 0).toUpperCase(); } // $toNULL : 将结果清空(用于只需要执行,不需要结果的函数) // 参数1-n : 任意表达式 else if("null".equalsIgnoreCase(methodName)) { return ""; } // $switch : 进行switch..case的操作,如果条件值为"##default##"则代表缺省值 // 参数1 : 要判断的key // 参数2,4,6... : 条件值 // 参数3,5,7... : 执行结果 else if("swtich".equalsIgnoreCase(methodName)) { String key = SMTEvalString.getParam(env, listParam, 0); String defVal = ""; for(int i = 1; i < listParam.size(); i += 2) { String cond = SMTEvalString.getParam(env, listParam, i + 0); String value1 = SMTEvalString.getParam(env, listParam, i + 1); if(cond.equals("##default##")) { defVal = value1; continue; } if(key.equalsIgnoreCase(cond)) return value1; } return defVal; } // $strcmp : 字符串判断 // 参数1: 值1 // 参数2:值2 // 参数3:是否忽略大小写(缺省不忽略) // 参数4: 根据预期结果返回0或1 else if("strcmp".equalsIgnoreCase(methodName)) { String v1 = SMTEvalString.getParam(env, listParam, 0); String v2 = SMTEvalString.getParam(env, listParam, 1); boolean ignoreCase = objectBoolValue(SMTEvalString.getParam(env, listParam, 2, "")); String compResult = trimString(SMTEvalString.getParam(env, listParam, 3, "")); Integer c = ignoreCase ? v1.compareToIgnoreCase(v2) : v1.compareTo(v2); if(c < 0) c = -1; else if(c > 0) c = 1; if(compResult.length() > 0) return compResult.equals(c.toString()) ? "1" : "0"; return c.toString(); } // $setArg : 将数值设置到arg变量中 // 参数1 : 变量名 // 参数2 : 值1 else if("setArg".equalsIgnoreCase(methodName)) { env.setArgValue(methodName, SMTEvalString.getNoEmptyParam(env, listParam, 0)); } // $setVarb : 将数值设置到内部变量中 // 参数1 : 变量名 // 参数2 : 值1 else if("setVarb".equalsIgnoreCase(methodName)) { env.setVarbValue(methodName, SMTEvalString.getNoEmptyParam(env, listParam, 0)); } // $getVarb : 将数值设置到内部变量中 // 参数1 : 变量名 // 参数2 : 缺省值(缺省标识找不到就报错) else if("getVarb".equalsIgnoreCase(methodName)) { String varbName = SMTEvalString.getNoEmptyParam(env, listParam, 0); String ret = env.getVarbValue(varbName, null); if(ret != null) return ret; if(listParam.size() < 2) throw new RuntimeException(String.format("can't get varb value [%s]", varbName)); else return SMTEvalString.getNoEmptyParam(env, listParam, 1); } // $EI : 计算整数表达式 // 参数:表达式 else if("EI".equalsIgnoreCase(methodName)) { String evalStr = SMTEvalString.getParam(env, listParam, 0); EvalCharIterator iterator = new EvalCharIterator(evalStr, "Long", '['); return ((Long)iterator.parseEval()).toString(); } // $EF : 计算浮点表达式 // 参数:表达式 else if("Ef".equalsIgnoreCase(methodName)) { String evalStr = SMTEvalString.getParam(env, listParam, 0); EvalCharIterator iterator = new EvalCharIterator(evalStr, "Double", '['); return String.format("%f", (Double)iterator.parseEval()); } } catch(Exception ex) { throw new RuntimeException(String.format("eval string method [%s] error", methodName), ex); } throw new RuntimeException(String.format("eval string method [%s] is not found", methodName)); } private static class EvalCharIterator extends CharIterator { enum EVAL_OP { EVAL_LEFT_XKH(0x01FF01), EVAL_SELF_SUB(0x010201), EVAL_LOGIC_NOT(0x010202), EVAL_BIT_NOT(0x010203), EVAL_DIV(0x020301), EVAL_MUL(0x020302), EVAL_MOD(0x020303), EVAL_ADD(0x020401), EVAL_SUB(0x020402), EVAL_BIT_LEFT(0x020501), EVAL_BIT_RIGHT(0x020502), EVAL_LOG_GR(0x020601), EVAL_LOG_GR_EQ(0x020602), EVAL_LOG_LS(0x020603), EVAL_LOG_LS_EQ(0x020604), EVAL_LOG_EQ(0x020701), EVAL_LOG_NO_EQ(0x020702), EVAL_BIT_AND(0x020801), EVAL_BIT_XOR(0x020901), EVAL_BIT_OR(0x021001), EVAL_LOG_AND(0x021101), EVAL_LOG_OR(0x021201); int value; EVAL_OP(int value) { this.value = value; } } enum EVAL_NUM_TYPE { None, Double, Long } private static Pattern _patNumber = Pattern.compile("[+-]?\\d+(?:\\.\\d+)?"); private char _startKH = '('; private char _endKH = ')'; private EVAL_NUM_TYPE _numType = EVAL_NUM_TYPE.None; private LinkedList listNum = new LinkedList(); private LinkedList listOp = new LinkedList(); public EvalCharIterator(String str, String numType, char KH) throws Exception { super(str); if(numType.equalsIgnoreCase("double")) _numType = EVAL_NUM_TYPE.Double; else if(numType.equalsIgnoreCase("Long")) _numType = EVAL_NUM_TYPE.Long; else throw new Exception("eval data type only double or Long, unsupport :" + numType); if(KH == '(') { _startKH = '('; _endKH = ')'; } else if(KH == '[') { _startKH = '['; _endKH = ']'; } else if(KH == '{') { _startKH = '{'; _endKH = '}'; } else throw new Exception(String.format("kuohao only set to ( [ {, unsupport: %c", KH)); } public Object parseNumber(boolean expError) throws Exception { Matcher m = _patNumber.matcher(_str); if(m.find(_pos) && m.start() == _pos) { String value = m.group(); _pos += value.length(); switch(_numType) { case Double:return Double.parseDouble(value); case Long:return Long.parseLong(value); default: break; } } if(expError) throw new Exception(this.getErrMsg("can't parse number")); return null; } public Object parseEval() throws Exception { boolean prevNum = false; while(this.skipSpace()) { char ch = this.getChar(false); // 如果第一个字符是数字,则取数字 if(ch >= '0' && ch <= '9') { listNum.addLast(this.parseNumber(true)); prevNum = true; continue; } // 如果是左括号,则将其压入栈中 if(ch == _startKH) { if(prevNum) throw new Exception(this.getErrMsg("'(' prev can't be number")); listOp.addLast(EVAL_OP.EVAL_LEFT_XKH); } // 如果是右括号,则做退栈处理 else if(ch == _endKH) { boolean find = false; // 计算所有残留在栈中的数据 while(listOp.size() > 0) { EVAL_OP op = listOp.getLast(); // 如果栈顶的操作不是左括号,则做退栈操作 if(op != EVAL_OP.EVAL_LEFT_XKH) { execCalcOp(); } // 如果栈顶是左括号,则退出左括号,并退出循环 else { listOp.removeLast(); find = true; break; } } // 如果未发现左括号,则报错 if(!find) throw new Exception(this.getErrMsg("can't find matching '('")); } // 非数字则认为是操作符 else if(ch == '<') { this.getChar(true); // 跳过当前字符 ch = this.getChar(false); // 获取下一个字符 boolean skipCur = true; switch(ch) { case '<': calcEval(EVAL_OP.EVAL_BIT_LEFT, prevNum); break; case '=': calcEval(EVAL_OP.EVAL_LOG_LS_EQ, prevNum); break; default: calcEval(EVAL_OP.EVAL_LOG_LS, prevNum); skipCur = false; break; } if(skipCur) this.getChar(true); // 跳过当前字符 } else if(ch == '>') { this.getChar(true); // 跳过当前字符 ch = this.getChar(false); // 获取下一个字符 boolean skipCur = true; switch(ch) { case '>': calcEval(EVAL_OP.EVAL_BIT_RIGHT, prevNum); break; case '=': calcEval(EVAL_OP.EVAL_LOG_GR_EQ, prevNum); break; default: calcEval(EVAL_OP.EVAL_LOG_GR, prevNum); skipCur = false; break; } if(skipCur) this.getChar(true); // 跳过当前字符 } else if(ch == '=') { this.getChar(true); // 跳过当前字符 if(this.getChar(true) != '=') throw new Exception(this.getErrMsg("can't find '=='")); calcEval(EVAL_OP.EVAL_LOG_EQ, prevNum); } else if(ch == '!') { this.getChar(true); // 跳过当前字符 ch = this.getChar(false); // 获取下一个字符 boolean skipCur = true; switch(ch) { case '=': calcEval(EVAL_OP.EVAL_LOG_NO_EQ, prevNum); break; default: calcEval(EVAL_OP.EVAL_LOGIC_NOT, prevNum); skipCur = false; break; } if(skipCur) this.getChar(true); // 跳过当前字符 } else if(ch == '&') { this.getChar(true); // 跳过当前字符 ch = this.getChar(false); // 获取下一个字符 boolean skipCur = true; switch(ch) { case '&': calcEval(EVAL_OP.EVAL_LOG_AND, prevNum); break; default: calcEval(EVAL_OP.EVAL_BIT_AND, prevNum); skipCur = false; break; } if(skipCur) this.getChar(true); // 跳过当前字符 } else if(ch == '|') { this.getChar(true); // 跳过当前字符 ch = this.getChar(false); // 获取下一个字符 boolean skipCur = true; switch(ch) { case '|': calcEval(EVAL_OP.EVAL_LOG_OR, prevNum); break; default: calcEval(EVAL_OP.EVAL_BIT_OR, prevNum); skipCur = false; break; } if(skipCur) this.getChar(true); // 跳过当前字符 } // 无歧义的单个运算符 else { switch(ch) { case '-': calcEval(prevNum ? EVAL_OP.EVAL_SUB : EVAL_OP.EVAL_SELF_SUB, prevNum); break; case '~': calcEval(EVAL_OP.EVAL_BIT_NOT, prevNum); break; case '/': calcEval(EVAL_OP.EVAL_DIV, prevNum); break; case '*': calcEval(EVAL_OP.EVAL_MUL, prevNum); break; case '%': calcEval(EVAL_OP.EVAL_MOD, prevNum); break; case '+': calcEval(EVAL_OP.EVAL_ADD, prevNum); break; case '^': calcEval(EVAL_OP.EVAL_BIT_XOR, prevNum); break; default: throw new Exception(this.getErrMsg(String.format("unknow operator : %c", ch))); } } this.getChar(true); // 跳过当前字符 prevNum = false; } // 计算所有残留在栈中的数据 while(listOp.size() > 0) { execCalcOp(); } // 判断栈中是否只有一个值 if(listNum.size() != 1) throw new Exception("number is out of bound"); return listNum.getLast(); } private void calcEval(EVAL_OP op, boolean prevNum) throws Exception { // 如果发现的是双目运算符,且前置不是数字的情况下报语法错误 if(((op.value & 0xFF0000) == 0x020000) && !prevNum) throw new Exception(this.getErrMsg("operate is not self:" + op.toString())); // 获取op列表中栈顶 while(listOp.size() > 0) { EVAL_OP lastOp = listOp.getLast(); // 如果栈顶的操作优先级不小于当前操作,则先做退栈操作 if((lastOp.value & 0x00FF00) <= (op.value & 0x00FF00)) { execCalcOp(); } // 如果栈顶的操作优先级小于当前操作,则不再继续退栈 else { break; } } // 将当前操作压入栈顶 listOp.addLast(op); } private void execCalcOp() throws Exception { // 获取栈顶的操作符 EVAL_OP lastOp = listOp.removeLast(); // 获取需要的操作数据 int argCount = lastOp.value >> 16; if(listNum.size() < argCount) throw new Exception("argument count not enough for op"); Object[] values = new Object[argCount]; for(int i = argCount - 1; i >= 0; i --) values[i] = listNum.removeLast(); // 进行运算操作 Object result = null; switch(lastOp) { case EVAL_SELF_SUB: if(values[0] instanceof Double) result = -(Double)values[0]; else if(values[0] instanceof Long) result = -(Long)values[0]; break; case EVAL_LOGIC_NOT: if(values[0] instanceof Double) result = (double)((Double)values[0] == 0 ? 1 : 0); else if(values[0] instanceof Long) result = (long)((Long)values[0] == 0 ? 1 : 0); break; case EVAL_BIT_NOT: if(values[0] instanceof Long) result = (long)(~(Long)values[0]); break; case EVAL_DIV: if(values[0] instanceof Double) result = (Double)values[0] / (Double)values[1]; else if(values[0] instanceof Long) result = (Long)values[0] / (Long)values[1]; break; case EVAL_MUL: if(values[0] instanceof Double) result = (Double)values[0] * (Double)values[1]; else if(values[0] instanceof Long) result = (Long)values[0] * (Long)values[1]; break; case EVAL_MOD: if(values[0] instanceof Long) result = (Long)values[0] % (Long)values[1]; break; case EVAL_ADD: if(values[0] instanceof Double) result = (Double)values[0] + (Double)values[1]; else if(values[0] instanceof Long) result = (Long)values[0] + (Long)values[1]; break; case EVAL_SUB: if(values[0] instanceof Double) result = (Double)values[0] - (Double)values[1]; else if(values[0] instanceof Long) result = (Long)values[0] - (Long)values[1]; break; case EVAL_BIT_LEFT: if(values[0] instanceof Long) result = (Long)values[0] << (Long)values[1]; break; case EVAL_BIT_RIGHT: if(values[0] instanceof Long) result = (Long)values[0] >> (Long)values[1]; break; case EVAL_LOG_GR: if(values[0] instanceof Double) result = (double)(((Double)values[0] > (Double)values[1]) ? 1 : 0); else if(values[0] instanceof Long) result = (long)(((Long)values[0] > (Long)values[1]) ? 1 : 0); break; case EVAL_LOG_GR_EQ: if(values[0] instanceof Double) result = (double)(((Double)values[0] >= (Double)values[1]) ? 1 : 0); else if(values[0] instanceof Long) result = (long)(((Long)values[0] >= (Long)values[1]) ? 1 : 0); break; case EVAL_LOG_LS: if(values[0] instanceof Double) result = (double)(((Double)values[0] < (Double)values[1]) ? 1 : 0); else if(values[0] instanceof Long) result = (long)(((Long)values[0] < (Long)values[1]) ? 1 : 0); break; case EVAL_LOG_LS_EQ: if(values[0] instanceof Double) result = (double)(((Double)values[0] <= (Double)values[1]) ? 1 : 0); else if(values[0] instanceof Long) result = (long)(((Long)values[0] <= (Long)values[1]) ? 1 : 0); break; case EVAL_LOG_EQ: if(values[0] instanceof Double) result = (double)(((Double)values[0] == (Double)values[1]) ? 1 : 0); else if(values[0] instanceof Long) result = (long)(((Long)values[0] == (Long)values[1]) ? 1 : 0); break; case EVAL_LOG_NO_EQ: if(values[0] instanceof Double) result = (double)(((Double)values[0] == (Double)values[1]) ? 1 : 0); else if(values[0] instanceof Long) result = (long)(((Long)values[0] == (Long)values[1]) ? 1 : 0); break; case EVAL_BIT_AND: if(values[0] instanceof Long) result = (Long)values[0] & (Long)values[1]; break; case EVAL_BIT_XOR: if(values[0] instanceof Long) result = (Long)values[0] ^ (Long)values[1]; break; case EVAL_BIT_OR: if(values[0] instanceof Long) result = (Long)values[0] | (Long)values[1]; break; case EVAL_LOG_AND: if(values[0] instanceof Double) result = (double)(Integer)(((Double)values[0] != 0 && (Double)values[1] != 0) ? 1 : 0); else if(values[0] instanceof Long) result = (long)(((Long)values[0] != 0 && (Long)values[1] != 0) ? 1 : 0); break; case EVAL_LOG_OR: if(values[0] instanceof Double) result = (double)(((Double)values[0] != 0 || (Double)values[1] != 0) ? 1 : 0); else if(values[0] instanceof Long) result = (long)(((Long)values[0] != 0 || (Long)values[1] != 0) ? 1 : 0); break; default: throw new Exception("operator is not support:" + lastOp.toString()); } if(result == null) throw new Exception("value type is not support for op : " + lastOp.toString()); listNum.addLast(result); } } }