Esempio n. 1
0
        /// <summary>
        /// 读取下一个表达式节点,如果读取失败则返回null
        /// </summary>
        /// <returns></returns>
        public ExpressionNode ReadNode()
        {
            //空格的位置
            int whileSpacePos = -1;

            StringBuilder buffer = new StringBuilder(10);
            while (this._Position < this._Expression.Length)
            {
                char c = this._Expression[this._Position];

                //空白字符不处理
                if (ExpressionNode.IsWhileSpace(c))
                {
                    //判断两次的空白字符是否连续
                    if (whileSpacePos >= 0 && (this._Position - whileSpacePos) > 1)
                    {
                        throw new ExpressionException(string.Format("表达式\"{0}\"在位置({1})上的字符非法!", this._Expression, this._Position));
                    }
                    else
                    {
                        if (buffer.Length == 0)
                        {
                            //前空白不判断处理
                            whileSpacePos = -1;
                        }
                        else
                        {
                            whileSpacePos = this._Position;
                        }
                        this._Position++;
                    }
                    continue;
                }

                if (buffer.Length == 0 || ExpressionNode.IsCongener(c, buffer[buffer.Length - 1]))
                {
                    //同一类字符则继续读取字符
                    this._Position++;
                    buffer.Append(c);
                }
                else
                {
                    break;
                }

                //判断是否需要更多的操作符
                if (!ExpressionNode.NeedMoreOperator(c)) break;
            }

            if (buffer.Length == 0) return null;

            ExpressionNode expNode = new ExpressionNode(buffer.ToString());
            if (expNode.Type == ExpressionNodeType.Unknown)
            {
                throw new ExpressionException(string.Format("表达式\"{0}\"在位置({1})上的字符\"{2}\"非法!",
                    this._Expression, this._Position - expNode.Value.Length, expNode.Value));
            }

            return expNode;
        }
        /// <summary>
        /// 对逆波兰表达式进行计算
        /// </summary>
        /// <param name="nodes"></param>
        /// <returns></returns>
        private static object CalcExpression(List <ExpressionNode> nodes)
        {
            if (nodes == null || nodes.Count == 0)
            {
                return(null);
            }

            #region 计算表达式
            if (nodes.Count > 1)
            {
                int index = 0;
                //储存数据
                ArrayList values = new ArrayList();
                while (index < nodes.Count)
                {
                    ExpressionNode node = nodes[index];

                    switch (node.Type)
                    {
                    //如果是数字,则将值存入 values 中
                    case ExpressionNodeType.Numeric:
                        values.Add(node.Numeric);
                        index++;
                        break;

                    default:
                        //二元表达式,需要二个参数, 如果是Not的话,则只要一个参数
                        int paramCount = 2;
                        if (node.Type == ExpressionNodeType.Not)
                        {
                            paramCount = 1;
                        }
                        //计算操作数的值
                        if (values.Count < paramCount)
                        {
                            throw new ExpressionException("缺少操作数");
                        }
                        //传入参数
                        object[] data = new object[paramCount];
                        for (int i = 0; i < paramCount; i++)
                        {
                            data[i] = values[index - paramCount + i];
                        }
                        //将计算结果再存入当前节点
                        node.Numeric = Calculate(node.Type, data);
                        node.Type    = ExpressionNodeType.Numeric;
                        //将操作数节点删除
                        for (int i = 0; i < paramCount; i++)
                        {
                            nodes.RemoveAt(index - i - 1);
                            values.RemoveAt(index - i - 1);
                        }
                        index -= paramCount;
                        break;
                    }
                }
            }

            if (nodes.Count == 1)
            {
                switch (nodes[0].Type)
                {
                case ExpressionNodeType.Numeric:
                    return(nodes[0].Numeric);

                default:
                    throw new ExpressionException("缺少操作数");
                }
            }
            else
            {
                throw new ExpressionException("缺少操作符或操作数");
            }
            #endregion
        }
        /// <summary>
        /// 将算术表达式转换为逆波兰表达式
        /// </summary>
        /// <param name="expression">要计算的表达式,如"1+2+3+4"</param>
        private static List <ExpressionNode> ParseExpression(string expression)
        {
            if (string.IsNullOrEmpty(expression))
            {
                return(new List <ExpressionNode>());
            }

            List <ExpressionNode>  listOperator  = new List <ExpressionNode>(10);
            Stack <ExpressionNode> stackOperator = new Stack <ExpressionNode>(5);

            ExpressionParser expParser     = new ExpressionParser(expression);
            ExpressionNode   beforeExpNode = null;     //前一个节点
            ExpressionNode   unitaryNode   = null;     //一元操作符
            ExpressionNode   expNode;

            //是否需要操作数
            bool requireOperand = false;

            #region 分析表达式

            while ((expNode = expParser.ReadNode()) != null)
            {
                if (expNode.Type == ExpressionNodeType.Numeric)
                {
                    //操作数, 直接加入后缀表达式中
                    if (unitaryNode != null)
                    {
                        //设置一元操作符节点
                        expNode.UnitaryNode = unitaryNode;
                        unitaryNode         = null;
                    }

                    listOperator.Add(expNode);
                    requireOperand = false;
                }
                else if (expNode.Type == ExpressionNodeType.LParentheses)
                {
                    //左括号, 直接加入操作符栈
                    stackOperator.Push(expNode);
                }
                else if (expNode.Type == ExpressionNodeType.RParentheses)
                {
                    //右括号则在操作符栈中反向搜索,直到遇到匹配的左括号为止,将中间的操作符依次加到后缀表达式中。
                    ExpressionNode lpNode = null;
                    while (stackOperator.Count > 0)
                    {
                        lpNode = stackOperator.Pop();
                        if (lpNode.Type == ExpressionNodeType.LParentheses)
                        {
                            break;
                        }
                        listOperator.Add(lpNode);
                    }
                    if (lpNode == null || lpNode.Type != ExpressionNodeType.LParentheses)
                    {
                        throw new ExpressionException(string.Format("在表达式\"{0}\"中没有与在位置({1})上\")\"匹配的\"(\"字符!", expParser.Expression, expParser.Position));
                    }
                }
                else
                {
                    if (stackOperator.Count == 0)
                    {
                        //第一个节点则判断此节点是否是一元操作符"+,-,!,("中的一个,否则其它都非法
                        if (listOperator.Count == 0 &&
                            !(expNode.Type == ExpressionNodeType.LParentheses || expNode.Type == ExpressionNodeType.Not))
                        {
                            //后缀表达式没有任何数据则判断是否是一元操作数
                            if (ExpressionNode.IsUnitaryNode(expNode.Type))
                            {
                                unitaryNode = expNode;
                            }
                            else
                            {
                                //丢失操作数
                                throw new ExpressionException(string.Format("表达式\"{0}\"在位置({1})上缺少操作数!", expParser.Expression, expParser.Position));
                            }
                        }
                        else
                        {
                            //直接压入操作符栈
                            stackOperator.Push(expNode);
                        }
                        requireOperand = true;          //下一个节点需要操作数
                    }
                    else
                    {
                        if (requireOperand)
                        {
                            //如果需要操作数则判断当前的是否是"+","-"号(一元操作符),如果是则继续
                            if (ExpressionNode.IsUnitaryNode(expNode.Type) && unitaryNode == null)
                            {
                                unitaryNode = expNode;
                            }
                            else
                            {
                                //丢失操作数
                                throw new ExpressionException(string.Format("表达式\"{0}\"在位置({1})上缺少操作数!", expParser.Expression, expParser.Position));
                            }
                        }
                        else
                        {
                            //对前面的所有操作符进行优先级比较
                            do
                            {
                                //取得上一次的操作符
                                beforeExpNode = stackOperator.Peek();

                                //如果前一个操作符优先级较高,则将前一个操作符加入后缀表达式中
                                if (beforeExpNode.Type != ExpressionNodeType.LParentheses && (beforeExpNode.PRI - expNode.PRI) >= 0)
                                {
                                    listOperator.Add(stackOperator.Pop());
                                }
                                else
                                {
                                    break;
                                }
                            } while (stackOperator.Count > 0);

                            //将操作符压入操作符栈
                            stackOperator.Push(expNode);
                            requireOperand = true;
                        }
                    }
                }
            }

            if (requireOperand)
            {
                //丢失操作数
                throw new ExpressionException(string.Format("表达式\"{0}\"在位置({1})上缺少操作数!", expParser.Expression, expParser.Position));
            }
            //清空堆栈
            while (stackOperator.Count > 0)
            {
                //取得操作符
                beforeExpNode = stackOperator.Pop();
                if (beforeExpNode.Type == ExpressionNodeType.LParentheses)
                {
                    throw new ExpressionException(string.Format("表达式\"{0}\"中括号不匹配,丢失右括号!", expParser.Expression, expParser.Position));
                }
                listOperator.Add(beforeExpNode);
            }
            #endregion

            return(listOperator);
        }
Esempio n. 4
0
        /// <summary>
        /// 读取下一个表达式节点,如果读取失败则返回null
        /// </summary>
        /// <returns></returns>
        public ExpressionNode ReadNode()
        {
            //空格的位置
            int whileSpacePos = -1;

            StringBuilder buffer = new StringBuilder(10);

            while (this._Position < this._Expression.Length)
            {
                char c = this._Expression[this._Position];

                //空白字符不处理
                if (ExpressionNode.IsWhileSpace(c))
                {
                    //判断两次的空白字符是否连续
                    if (whileSpacePos >= 0 && (this._Position - whileSpacePos) > 1)
                    {
                        throw new ExpressionException(string.Format("表达式\"{0}\"在位置({1})上的字符非法!", this._Expression, this._Position));
                    }
                    else
                    {
                        if (buffer.Length == 0)
                        {
                            //前空白不判断处理
                            whileSpacePos = -1;
                        }
                        else
                        {
                            whileSpacePos = this._Position;
                        }
                        this._Position++;
                    }
                    continue;
                }

                if (buffer.Length == 0 || ExpressionNode.IsCongener(c, buffer[buffer.Length - 1]))
                {
                    //同一类字符则继续读取字符
                    this._Position++;
                    buffer.Append(c);
                }
                else
                {
                    break;
                }

                //判断是否需要更多的操作符
                if (!ExpressionNode.NeedMoreOperator(c))
                {
                    break;
                }
            }

            if (buffer.Length == 0)
            {
                return(null);
            }

            ExpressionNode expNode = new ExpressionNode(buffer.ToString());

            if (expNode.Type == ExpressionNodeType.Unknown)
            {
                throw new ExpressionException(string.Format("表达式\"{0}\"在位置({1})上的字符\"{2}\"非法!",
                                                            this._Expression, this._Position - expNode.Value.Length, expNode.Value));
            }

            return(expNode);
        }