Exemplo n.º 1
0
        public static Expression <Func <T, bool> > ToExpression <T>(this AxiomFilter filter)
        {
            var axDict = GetAxiomExpressionDictionary <T>(filter);

            filter.Format = filter.Format.Replace(AND_ALSO, AND).Replace(OR_ELSE, OR);

            var junctionDict = new Dictionary <string, Func <Expression <Func <T, bool> >, Expression <Func <T, bool> >, Expression <Func <T, bool> > > >()
            {
                { AND, TypeExtensions.AndAlso },
                { OR, TypeExtensions.OrElse }
            };

            Func <string, bool> IsBinOperator = (string s) =>
            {
                return(s == AND || s == OR);
            };

            Func <string, bool> IsUnaryOperator = (string s) =>
            {
                return(s == NOT);
            };

            Func <object, Expression <Func <T, bool> > > GetAxiomFunc = (object o) =>
            {
                if (!(o is Token))
                {
                    return(o as Expression <Func <T, bool> >);
                }

                return(axDict[((Token)o).Value]);
            };


            using (var reader = new StringReader(filter.Format))
            {
                var parser       = new Parser();
                var tokens       = parser.Tokenize(reader).ToList();
                var rpn          = parser.ShuntingYard(tokens).ToList();
                var processStack = new Stack <object>();
                var i            = 0;

                do
                {
                    var t = rpn[i];
                    if (IsBinOperator(t.Value))
                    {
                        processStack.Push(
                            junctionDict[t.Value](
                                GetAxiomFunc(processStack.Pop()),
                                GetAxiomFunc(processStack.Pop())
                                )
                            );
                    }
                    else if (IsUnaryOperator(t.Value))
                    {
                        processStack.Push(
                            TypeExtensions.Not(
                                GetAxiomFunc(processStack.Pop())
                                )
                            );
                    }
                    else
                    {
                        processStack.Push(t);
                    }

                    i++;
                }while (i < rpn.Count);

                var exp = processStack.Pop() as Expression <Func <T, bool> >;

                return((exp.CanReduce)
                    ? exp.Reduce() as Expression <Func <T, bool> >
                    : exp);
            }
        }
Exemplo n.º 2
0
        private static Dictionary <string, Expression <Func <T, bool> > > GetAxiomExpressionDictionary <T>(AxiomFilter filter)
        {
            var type            = typeof(T);
            var axiomDict       = new Dictionary <string, Expression <Func <T, bool> > >();
            var paramExpression = Expression.Parameter(type, "🖕🏽");

            foreach (var a in filter.Axioms)
            {
                var conditionalExpression = a.ToExpression <T>(paramExpression);
                axiomDict.Add($"{{{a.Key}}}", conditionalExpression);
            }

            return(axiomDict);
        }