Ejemplo n.º 1
0
        /// <summary>
        ///  Filter expression can be a literal string, "Hello World"  or  it can contain logical
        ///  conjunctions "or" and "and", like this "Hello and Hi" or "Hello & Hi" or "Hello or Hi"
        ///  and it can have parentheses "Hello and (foo or bar)" and so on.  It can also have
        ///  a "not" or "!" for negation.
        /// </summary>
        public Filter <T> Parse(string quickFilter)
        {
            if (string.IsNullOrWhiteSpace(quickFilter))
            {
                return(null);
            }

            foreach (Tuple <QuickFilterToken, string> token in GetFilterTokens(quickFilter))
            {
                string literal = token.Item2;

                switch (token.Item1)
                {
                case QuickFilterToken.Literal:     // shift
                    stack.Push(new FilterKeyword <T>(new FilterLiteral(literal)));
                    break;

                case QuickFilterToken.And:     // reduce
                    stack.Push(new FilterAnd <T>()
                    {
                        Left = Reduce(QuickFilterToken.And)
                    });
                    break;

                case QuickFilterToken.Or:     // reduce
                    stack.Push(new FilterOr <T>()
                    {
                        Left = Reduce(QuickFilterToken.Or)
                    });
                    break;

                case QuickFilterToken.Not:     // reduce
                    stack.Push(new FilterNot <T>()
                    {
                    });
                    break;

                case QuickFilterToken.LeftParen:     // shift
                    stack.Push(new FilterParens <T>());
                    break;

                case QuickFilterToken.RightParen:     // reduce
                    Filter <T>       op     = Reduce(QuickFilterToken.RightParen);
                    FilterParens <T> parens = op as FilterParens <T>;
                    if (parens != null)
                    {
                        // eliminate parens
                        stack.Push(parens.Expression);
                    }
                    else
                    {
                        // missing open parens, now what?
                        stack.Push(op);
                    }
                    break;
                }
            }

            return(Reduce(QuickFilterToken.None));
        }
Ejemplo n.º 2
0
        private Filter <T> Reduce(QuickFilterToken token)
        {
            while (stack.Count > 0)
            {
                Filter <T> top = stack.Pop();

                if (stack.Count == 0)
                {
                    return(top);
                }

                Filter <T> op = stack.Peek();
                if (token > op.Precidence)
                {
                    return(top);
                }

                op = stack.Pop();

                // now combine "top" and "op"
                if (op is FilterKeyword <T> )
                {
                    FilterKeyword <T> keyword = (FilterKeyword <T>)op;
                    op = Combine(keyword, top);
                }
                else if (op is FilterAnd <T> )
                {
                    FilterAnd <T> and = (FilterAnd <T>)op;
                    and.Right = Combine(and.Right, top);
                }
                else if (op is FilterOr <T> )
                {
                    FilterOr <T> or = (FilterOr <T>)op;
                    or.Right = Combine(or.Right, top);
                }
                else if (op is FilterNot <T> )
                {
                    FilterNot <T> not = (FilterNot <T>)op;
                    not.Right = Combine(not.Right, top);
                }
                else if (op is FilterParens <T> )
                {
                    FilterParens <T> parens = (FilterParens <T>)op;
                    parens.Expression = Combine(parens.Expression, top);
                }
                stack.Push(op);
            }
            return(null);
        }