Exemplo n.º 1
0
        /// <summary>
        ///     Evaluate the expression using provided variables
        /// </summary>
        /// <param name="expression">The expression to evaluate</param>
        /// <returns></returns>
        public bool Evaluate(string expression)
        {
            var  stack  = new Stack <bool>();
            bool result = false;

            foreach (ITypedToken exp in ExpressionParser.Parse(expression))
            {
                switch (exp.TokenType)
                {
                case TokenType.Value:
                    result = ((ConstantToken)exp).Value;
                    break;

                case TokenType.Variable:
                    var var = (VariableToken)exp;
                    if (!variables.TryGetValue((ignoreCase ? var.Name.ToUpper() : var.Name), out result))
                    {
                        throw new InvalidOperationException("Trying to evaluate an unknown variable named '" +
                                                            var.Name + "', please check your variable dictionary!");
                    }
                    break;

                case TokenType.Operator:
                    var op = (OperatorToken)exp;
                    if (op.IsUnary)
                    {
                        result = OperatorHelper.EvaluateUnary(op.Operator, stack.Pop());
                    }
                    else     // binary operator
                    {
                        bool p2 = stack.Pop();
                        bool p1 = stack.Pop();
                        result = OperatorHelper.EvaluateBinary(op.Operator, p1, p2);
                    }
                    break;
                }
                stack.Push(result);
            }

            return(stack.Pop());
        }
Exemplo n.º 2
0
        /// <summary>
        ///     Converts the input infix expression into the postfix and creates the list
        ///     of token in that order
        /// </summary>
        /// <param name="expression">Infix expression (e.g. (A && C) || B)</param>
        /// <returns>List of atomic expressions sorted in the postfix order</returns>
        public static IEnumerable <ITypedToken> Parse(string expression)
        {
            var    expressions   = new List <ITypedToken>();
            string variable      = string.Empty;
            var    operatorStack = new Stack <string>();

            try
            {
                for (int i = 0; i < expression.Length; i++)
                {
                    char c = expression[i];

                    if (IgnoredCharsList.Contains(c))
                    {
                        continue;                               // ignore some characters
                    }
                    // variable or number
                    if (IsVariableNameCharacter(c))
                    {
                        variable += c;
                    }
                    else
                    {
                        switch (c)
                        {
                        case '(':
                            operatorStack.Push(Constant.LeftParenthesis);
                            break;

                        case ')':
                            CheckVariable(variable, expressions);
                            variable = string.Empty;
                            while (!operatorStack.Peek().Equals(Constant.LeftParenthesis))
                            {
                                expressions.Add(new OperatorToken {
                                    Operator = operatorStack.Pop()
                                });
                            }
                            operatorStack.Pop();
                            break;

                        default:
                            string sc = c.ToString(CultureInfo.InvariantCulture);
                            CheckVariable(variable, expressions);
                            variable = string.Empty;
                            if (i < expression.Length - 1)
                            {
                                char next = expression[i + 1];
                                if (!IgnoredCharsList.Contains(c) && !IsVariableNameCharacter(next) && next != '(' && next != ')')
                                {
                                    sc += next;
                                    i++;
                                }
                            }
                            while (operatorStack.Count > 0 &&
                                   OperatorHelper.Priority(operatorStack.Peek()) >= OperatorHelper.Priority(sc))
                            {
                                expressions.Add(new OperatorToken {
                                    Operator = operatorStack.Pop()
                                });
                            }
                            operatorStack.Push(sc);
                            break;
                        }
                    }
                }

                CheckVariable(variable, expressions);
                while (operatorStack.Count > 0)
                {
                    expressions.Add(new OperatorToken {
                        Operator = operatorStack.Pop()
                    });
                }
            }
            catch (Exception)
            {
                throw new InvalidOperationException("Cannot parse the current expression '" + expression + "'!");
            }

            if (expressions.Count == 0)
            {
                throw new InvalidOperationException("Cannot evaluate an empty expression!");
            }

            return(expressions);
        }