示例#1
0
 /// <summary>
 /// Create a new filter expression 'Or'ing 'this' with 'filter'.
 /// </summary>
 private FilterExpression Or(FilterExpression filter)
 {
     return(new FilterExpression(this, filter, false));
 }
示例#2
0
        /// <summary>
        /// Return FilterExpression after parsing the given filter expression.
        /// </summary>
        internal static FilterExpression Parse(string filterString)
        {
            ValidateArg.NotNull(filterString, "filterString");

            // below parsing doesn't error out on pattern (), so explicitly search for that (empty parethesis).
            var invalidInput = Regex.Match(filterString, @"\(\s*\)");

            if (invalidInput.Success)
            {
                throw new FormatException(string.Format(CultureInfo.CurrentCulture, CommonResources.TestCaseFilterFormatException, CommonResources.EmptyParenthesis));
            }

            var tokens        = Regex.Split(filterString, filterExpressionSeperatorString);
            var operatorStack = new Stack <Operator>();
            var filterStack   = new Stack <FilterExpression>();

            // This is based on standard parsing of inorder expression using two stacks (operand stack and operator stack)
            // Predence(And) > Predence(Or)
            foreach (var inputToken in tokens)
            {
                var token = inputToken.Trim();
                if (string.IsNullOrEmpty(token))
                {
                    // ignore empty tokens
                    continue;
                }

                switch (token)
                {
                case "&":
                case "|":
                    Operator currentOperator = Operator.And;
                    if (string.Equals("|", token))
                    {
                        currentOperator = Operator.Or;
                    }

                    // Always put only higher priority operator on stack.
                    //  if lesser prioriy -- pop up the stack and process the operator to maintain operator precedence.
                    //  if equal priority -- pop up the stack and process the operator to maintain operator associativity.
                    //  OpenBrace is special condition. & or | can come on top of OpenBrace for case like ((a=b)&c=d)
                    while (true)
                    {
                        bool     isEmpty          = operatorStack.Count == 0;
                        Operator stackTopOperator = isEmpty ? Operator.None : operatorStack.Peek();
                        if (isEmpty || stackTopOperator == Operator.OpenBrace || stackTopOperator < currentOperator)
                        {
                            operatorStack.Push(currentOperator);
                            break;
                        }
                        stackTopOperator = operatorStack.Pop();
                        ProcessOperator(filterStack, stackTopOperator);
                    }
                    break;

                case "(":
                    operatorStack.Push(Operator.OpenBrace);
                    break;

                case ")":
                    // process operators from the stack till OpenBrace is found.
                    // If stack is empty at any time, than matching OpenBrace is missing from the expression.
                    if (operatorStack.Count == 0)
                    {
                        throw new FormatException(string.Format(CultureInfo.CurrentCulture, CommonResources.TestCaseFilterFormatException, CommonResources.MissingOpenParenthesis));
                    }

                    Operator temp = operatorStack.Pop();
                    while (temp != Operator.OpenBrace)
                    {
                        ProcessOperator(filterStack, temp);
                        if (operatorStack.Count == 0)
                        {
                            throw new FormatException(string.Format(CultureInfo.CurrentCulture, CommonResources.TestCaseFilterFormatException, CommonResources.MissingOpenParenthesis));
                        }
                        temp = operatorStack.Pop();
                    }

                    break;

                default:
                    // push the operand to the operand stack.
                    Condition        condition = Condition.Parse(token);
                    FilterExpression filter    = new FilterExpression(condition);
                    filterStack.Push(filter);
                    break;
                }
            }
            while (operatorStack.Count != 0)
            {
                Operator temp = operatorStack.Pop();
                ProcessOperator(filterStack, temp);
            }

            if (filterStack.Count != 1)
            {
                throw new FormatException(string.Format(CultureInfo.CurrentCulture, CommonResources.TestCaseFilterFormatException, CommonResources.MissingOperator));
            }

            return(filterStack.Pop());
        }
示例#3
0
 /// <summary>
 /// Create a new filter expression 'And'ing 'this' with 'filter'.
 /// </summary>
 private FilterExpression And(FilterExpression filter)
 {
     return(new FilterExpression(this, filter, true));
 }