基于Java的简易表达式解析工具(二)

您所在的位置:网站首页 java条件表达式工具有哪些类 基于Java的简易表达式解析工具(二)

基于Java的简易表达式解析工具(二)

2024-07-11 21:17| 来源: 网络整理| 查看: 265

之前简单的介绍了这个基于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