コード例 #1
0
ファイル: Expression.cs プロジェクト: foxbill/xbase-2018.01
        /// <summary>
        /// 二元计算
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <param name="op"></param>
        /// <returns></returns>
        public object DyadicOperation(ExpNode left, ExpNode right, string symbol)
        {
            IOperator iOp = OperatorFactory.GetOperator(symbol);

            iOp.LeftOperand  = OperandOperation(left).ToString();
            iOp.RightOperand = OperandOperation(right).ToString();
            return(iOp.Eval());
            //            return iOp.Eval(;
        }
コード例 #2
0
        /// <summary>
        /// Algo of EvaluateRPN (source : Expression Evaluator : using RPN by lallous
        /// in the C++/MFC section of www.CodeProject.com.
        /// 1.	Initialize stack for storing results, prepare input postfix (or RPN) expression.
        ///	2.	Start scanning from left to right till we reach end of RPN expression
        ///	3.	Get token, if token is:
        ///		I.	An operator:
        ///			a.	Get top of stack and store into variable op2; Pop the stack
        ///			b.	Get top of stack and store into variable op1; Pop the stack
        ///			c.	Do the operation expression in operator on both op1 and op2
        ///			d.	Push the result into the stack
        ///		II.	An operand: stack its numerical representation into our numerical stack.
        ///	4.	At the end of the RPN expression, the stack should only have one value and
        ///	that should be the result and can be retrieved from the top of the stack.
        /// </summary>
        /// <param name=szExpr>Expression to be evaluated in RPNotation with
        /// single character variables</param>
        /// <param name=htValues>Values for each of the variables in the expression</param>
        ///
        public object EvaluateRPN(ArrayList arrExpr, Type varType, Hashtable htValues)
        {
            // initialize stack (integer stack) for results
            Stack stPad = new Stack();

            // begin loop : scan from left to right till end of RPN expression
            foreach (object var in arrExpr)
            {
                Operand   op1   = null;
                Operand   op2   = null;
                IOperator oprtr = null;
                // Get token
                // if token is
                if (var is IOperand)
                {
                    // Operand : push onto top of numerical stack
                    stPad.Push(var);
                }
                else if (var is IOperator)
                {
                    // Operator :
                    //		Pop top of stack into var 1 - op2 first as top of stack is rhs
                    op2 = (Operand)stPad.Pop();
                    if (htValues != null)
                    {
                        op2.Value = htValues[op2.Name];
                    }
                    //		Pop top of stack into var 2
                    op1 = (Operand)stPad.Pop();
                    if (htValues != null)
                    {
                        op1.Value = htValues[op1.Name];
                    }
                    //		Do operation exp for 'this' operator on var1 and var2
                    oprtr = (IOperator)var;
                    IOperand opRes = oprtr.Eval(op1, op2);
                    //		Push results onto stack
                    stPad.Push(opRes);
                }
            }
            //	end loop
            // stack ends up with single value with final result
            return(((Operand)stPad.Pop()).Value);
        }
コード例 #3
0
        /// <summary>
        /// Evalua una expresion dada en notacion postfijo.
        /// </summary>
        /// <param name="postfixExp">Expresion en postfijo a evaluar.</param>
        /// <returns>El valor resultante de la evaluacion.</returns>
        private string EvaluatePostfix(string postfixExp)
        {
            Stack <Operand> operandStack = new Stack <Operand>();

            string[] tokenArray = postfixExp.Split(' ');

            foreach (string pretoken in tokenArray)
            {
                Tokenizer           token      = new Tokenizer(pretoken);
                IEnumerator <Token> enumerator = token.GetTokens().GetEnumerator();

                while (enumerator.MoveNext())
                {
                    Token item = enumerator.Current;
                    switch (item.Type)
                    {
                    case TokenType.True:
                        operandStack.Push(new Operand(true));
                        break;

                    case TokenType.False:
                        operandStack.Push(new Operand(false));
                        break;

                    case TokenType.Constant:
                        operandStack.Push(new Operand(int.Parse(item.Value)));
                        break;

                    case TokenType.Minus:
                        if (enumerator.MoveNext() && enumerator.Current.Type != TokenType.Minus)
                        {
                            operandStack.Push(new Operand(int.Parse(enumerator.Current.Value) * -1));
                        }
                        else
                        {
                            goto case TokenType.Plus;
                        }

                        break;

                    case TokenType.Plus:
                    case TokenType.Asterisk:
                    case TokenType.Slash:
                    case TokenType.Percent:
                    case TokenType.Ampersand:
                    case TokenType.Caret:
                    case TokenType.Greater:
                    case TokenType.GreaterEqual:
                    case TokenType.Less:
                    case TokenType.LessEqual:
                    case TokenType.Equal:
                    case TokenType.NotEqual:
                        try
                        {
                            IOperator oper = Operations[item.Value];
                            Operand   op2  = operandStack.Pop();
                            Operand   op1  = operandStack.Pop();
                            operandStack.Push(oper.Eval(op1, op2));
                        }
                        catch (InvalidCastException e)
                        {
                            throw new InvalidOperationException("Incorrect expression.", e);
                        }
                        break;

                    default:
                        throw new InvalidOperationException("Incorrect input expression.");
                    }
                }
            }

            if (operandStack.Count == 1)
            {
                string result = operandStack.Pop().Value.ToString();
                return(result);
            }
            else
            {
                throw new Exception("Unknown error.");
            }
        }