基于Java的简易表达式解析工具(二) |
您所在的位置:网站首页 › java条件表达式工具有哪些类 › 基于Java的简易表达式解析工具(二) |
之前简单的介绍了这个基于Java表达式解析工具,现在把代码分享给大家,希望帮助到有需要的人们,这个分享代码中依赖了一些其他的类,这些类大家可以根据自己的情况进行导入,无非就是写字符串处理工具类,日期处理的工具类什么的。 这个Java的表达式解析的工具只用了5个类,而且写得也很简单明了,相信有一些编程经验的可以看懂这些处理的逻辑代码。 1、第一个类:ExpressionNodeType(表达式各个字符节点的类型枚举类) [java] view plain copy print? public enum ExpressionNodeType { Unknown, Plus,// + Subtract, /// - MultiPly,// * Divide,// / LParentheses,//( RParentheses, /// ) Mod,//% (求模,取余) Power,// ^ (次幂) BitwiseAnd, /// & (按位与) BitwiseOr,/// | (按位或) And,// && (逻辑与) Or, /// || (逻辑或) Not,/// ! (逻辑非) Equal,/// == (相等) Unequal,/// != 或 (不等于) GT, /// > (大于) LT, /// = (大于等于) LTOrEqual, /// 1)) { throw new ExpressionException(String.format("表达式\"%s\"在位置(%s)上的字符非法!", this.getExpression(), this.getPosition())); } if (buffer.length() == 0) { whileSpacePos = -1; } else { whileSpacePos = this.position; } this.position++; continue; } if ((buffer.length() == 0) || ExpressionNode.IsCongener(c, buffer.charAt(buffer.length() - 1))) { this.position++; buffer.append(c); } else { break; } if (!ExpressionNode.needMoreOperator(c)) { break; } } } if (buffer.length() == 0) { return null; } ExpressionNode node = new ExpressionNode(buffer.toString()); if (node.getType() == ExpressionNodeType.Unknown) { throw new ExpressionException(String.format("表达式\"%s\"在位置%s上的字符\"%s\"非法!", this.getExpression(), this.getPosition() - node.getValue().length(), node.getValue())); } return node; } } 这个类处理将待解析的表达式,解析并创建ExpressionNode对象。 5、第五个类:ExpressionEvaluator(解析公式并返回结果的类) [java] view plain copy print? public class ExpressionEvaluator { private ExpressionEvaluator() { } /** * 将算术表达式转换为逆波兰表达式 * @param expression 要计算的表达式,如"1+2+3+4" * @return */ private static List parseExpression(String expression) { if(StringUtils.isEmpty(expression)){ return new ArrayList(); } List listOperator = new ArrayList(10); Stack stackOperator = new Stack(); ExpressionParser expParser = new ExpressionParser(expression); ExpressionNode beforeExpNode = null; //前一个节点 ExpressionNode unitaryNode = null; //一元操作符 ExpressionNode expNode; //是否需要操作数 boolean requireOperand = false; while ((expNode = expParser.readNode()) != null) { if ( (expNode.getType() == ExpressionNodeType.Numeric) || (expNode.getType() == ExpressionNodeType.String) || (expNode.getType() == ExpressionNodeType.Date)) { //操作数, 直接加入后缀表达式中 if (unitaryNode != null) { //设置一元操作符节点 expNode.setUnitaryNode(unitaryNode); unitaryNode = null; } listOperator.add(expNode); requireOperand = false; continue; } else if (expNode.getType() == ExpressionNodeType.LParentheses) { //左括号, 直接加入操作符栈 stackOperator.push(expNode); continue; } else if (expNode.getType() == ExpressionNodeType.RParentheses) { //右括号则在操作符栈中反向搜索,直到遇到匹配的左括号为止,将中间的操作符依次加到后缀表达式中。 ExpressionNode lpNode = null; while (stackOperator.size() > 0) { lpNode = stackOperator.pop(); if (lpNode.getType() == ExpressionNodeType.LParentheses) break; listOperator.add(lpNode); } if (lpNode == null || lpNode.getType() != ExpressionNodeType.LParentheses) { throw new ExpressionException(String.format("在表达式\"%s\"中没有与在位置(%s)上\")\"匹配的\"(%s)\"字符!", expParser.getExpression(), expParser.getPosition())); } } else { if (stackOperator.size() == 0) { //第一个节点则判断此节点是否是一元操作符"+,-,!,("中的一个,否则其它都非法 if (listOperator.size() == 0 && !(expNode.getType() == ExpressionNodeType.LParentheses || expNode.getType() == ExpressionNodeType.Not)) { //后缀表达式没有任何数据则判断是否是一元操作数 if (ExpressionNode.IsUnitaryNode(expNode.getType())) { unitaryNode = expNode; } else { //丢失操作数 throw new ExpressionException(String.format("表达式\"%s\"在位置(%s)上缺少操作数!", expParser.getExpression(), expParser.getPosition())); } } else { //直接压入操作符栈 stackOperator.push(expNode); } requireOperand = true; //下一个节点需要操作数 continue; } else { if (requireOperand) { //如果需要操作数则判断当前的是否是"+","-"号(一元操作符),如果是则继续 if (ExpressionNode.IsUnitaryNode(expNode.getType()) && unitaryNode == null) { unitaryNode = expNode; } else { //丢失操作数 throw new ExpressionException(String.format("表达式\"%s\"在位置({1})上缺少操作数!", expParser.getExpression(), expParser.getPosition())); } } else { //对前面的所有操作符进行优先级比较 do { //取得上一次的操作符 beforeExpNode = stackOperator.peek(); //如果前一个操作符优先级较高,则将前一个操作符加入后缀表达式中 if (beforeExpNode.getType() != ExpressionNodeType.LParentheses && (beforeExpNode.getPri() - expNode.getPri()) >= 0) { listOperator.add(stackOperator.pop()); } else { break; } } while (stackOperator.size() > 0); //将操作符压入操作符栈 stackOperator.push(expNode); requireOperand = true; } } } } if (requireOperand) { //丢失操作数 throw new ExpressionException(String.format("表达式\"%s\"在位置({1})上缺少操作数!", expParser.getExpression(), expParser.getPosition())); } //清空堆栈 while (stackOperator.size() > 0) { //取得操作符 beforeExpNode = stackOperator.pop(); if (beforeExpNode.getType() == ExpressionNodeType.LParentheses) { throw new ExpressionException(String.format("表达式\"%s\"中括号不匹配,丢失右括号!", expParser.getExpression(), expParser.getPosition())); } listOperator.add(beforeExpNode); } return listOperator; } /** * 对逆波兰表达式进行计算 * @param nodes * @return */ private static Object CalcExpression(List nodes) { if (nodes == null || nodes.size() == 0) return null; if (nodes.size() > 1) { int index = 0; //储存数据 ArrayList values = new ArrayList(); while (index |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |