/// <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(; }
/// <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); }
/// <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."); } }