public static EvaluationResult Parse(string expression, Type type, BuildArgument arg)
        {
            try
            {
                var param    = type.CreateParameterExpression();
                var rootNode = Parse(new ExpressionReader(expression), param, arg);
                if (arg.InvalidProperties.Count > 0 || arg.InvalidVariables.Count > 0)
                {
                    return(new EvaluationResult
                    {
                        InvalidProperties = arg.InvalidProperties,
                        InvalidVariables = arg.InvalidVariables
                    });
                }

                var body = rootNode.Build(arg);

                return(new EvaluationResult
                {
                    Result = Expression.Lambda(body, param),
                    Succeeded = true
                });
            }
            catch (Exception ex)
            {
                return(new EvaluationResult
                {
                    Exception = ex,
                    InvalidProperties = new List <string>(0),
                    InvalidVariables = new List <string>(0),
                    InvalidValues = arg.InvalidValues
                });
            }
        }
Beispiel #2
0
 public override Expression Build(BuildArgument arg)
 {
     try
     {
         Expression left  = null;
         Expression right = null;
         Type       inOperatorDataType = typeof(string);
         if (Left is Constant c && Right is Property p)
         {
             if (c.Type == null)
             {
                 var propEx = (MemberExpression)p.Build(arg);
                 c.Type = propEx.Type;
                 left   = c.Build(arg);
                 right  = propEx;
             }
             else
             {
                 left  = c.Build(arg);
                 right = p.Build(arg);
             }
         }
         else if (Left is Property p2 && Right is Constant c2)
         {
             var propEx = (MemberExpression)p2.Build(arg);
             c2.Type = propEx.Type;
             left    = propEx;
             right   = c2.Build(arg);
         }
Beispiel #3
0
 public override Expression Build(BuildArgument arg)
 {
     try
     {
         return(Param.CreatePropertyExpression(arg.MapProperty(Name)));
     }
     catch (Exception ex)
     {
         throw new FormatException(GetErrorMessage(), ex);
     }
 }
        private static Node BuildNode(ParameterExpression param, GroupParser parser, BuildArgument arg)
        {
            if (parser.BuiltNode != null)
            {
                return(parser.BuiltNode);
            }
            var result = new Group {
                Node = BuildNode(param, parser.Body, arg), StartIndex = parser.StartIndex, StartChar = parser.StartChar
            };

            parser.BuiltNode = result;

            return(result);
        }
Beispiel #5
0
        public override Expression Build(BuildArgument arg)
        {
            ParseValues();
            var arr = Array.CreateInstance(Type, StringValues.Count);
            var i   = 0;

            StringValues.ForEach((p) =>
            {
                var value = p.Cast(Type);
                arr.SetValue(value, i++);
            });

            return(Expression.Constant(arr));
        }
Beispiel #6
0
 public override Expression Build(BuildArgument arg)
 {
     if (Node == null)
     {
         throw new FormatException(GetErrorMessage());
     }
     try
     {
         return(Expression.Not(Node.Build(arg)));
     }
     catch (Exception ex)
     {
         throw new FormatException(GetErrorMessage(), ex);
     }
 }
Beispiel #7
0
        public override Expression Build(BuildArgument arg)
        {
            try
            {
                if (IsVariable && arg.VariableResolver.TryResolve(Value, out var value))
                {
                    return(Expression.Constant(Convert.ChangeType(value, Type)));
                }

                return(Expression.Constant(Value.Cast(Type), Type));
            }
            catch (Exception ex)
            {
                arg.InvalidValues.Add(Value);
                throw new FormatException(GetErrorMessage(), ex);
            }
        }
Beispiel #8
0
        public override Expression Build(BuildArgument arg)
        {
            Operator = Operator.ToLower();
            switch (Operator)
            {
            case Interpreter.LogicalAnd:
            case Interpreter.LogicalAnd2:
                return(Expression.AndAlso(Left.Build(arg), Right.Build(arg)));

            case Interpreter.LogicalOr:
            case Interpreter.LogicalOr2:
                return(Expression.OrElse(Left.Build(arg), Right.Build(arg)));

            default:
                return(null);
            }
        }
        private static Node BuildNode(ParameterExpression param, ComparisonFunctionOperatorParser parser, List <Parser> list, ref int currentIndex, BuildArgument arg)
        {
            if (parser.BuiltNode != null)
            {
                return(parser.BuiltNode);
            }
            var result = new Comparison
            {
                Left       = BuildNode(param, list[currentIndex - 1], list, ref currentIndex, arg),
                Right      = BuildNode(param, parser.Body, arg),
                Operator   = GetStandardOperator(parser.Result),
                StartIndex = parser.StartIndex,
                StartChar  = parser.StartChar
            };

            parser.BuiltNode       = result;
            list[currentIndex - 1] = null;

            return(result);
        }
Beispiel #10
0
 public override Expression Build(BuildArgument arg)
 {
     return(Node.Build(arg));
 }
        private static Node BuildNode(ParameterExpression param, List <Parser> parsers, BuildArgument arg)
        {
            foreach (var step in BuildSteps)
            {
                for (var index = 0; index < parsers.Count; ++index)
                {
                    var parser = parsers[index];
                    if (parsers[index] != null && step(parser.GetType(), parser))
                    {
                        BuildNode(param, parser, parsers, ref index, arg);
                    }
                }

                parsers = parsers.Where(p => p != null).ToList();
            }

            return(parsers[0].BuiltNode);
        }
        private static Node Parse(ExpressionReader reader, ParameterExpression parameter, BuildArgument arg)
        {
            var acceptedParsers = GetBeginningParsers();
            var keepTrack       = false;
            var groups          = new Stack <Parser>();

            reader.IgnoreWhiteSpace();
            while (!reader.IsEnd)
            {
                var noOfWhiteSpaceIgnored = 0;
                if (!keepTrack)
                {
                    noOfWhiteSpaceIgnored = reader.IgnoreWhiteSpace();
                }
                var c       = reader.Read();
                var parsers = acceptedParsers;
                acceptedParsers = new List <Parser>();
                var    isStartGroup = false;
                Parser group        = null;
                foreach (var parser in parsers)
                {
                    if (parser.Accept(c, noOfWhiteSpaceIgnored, reader.CurrentIndex, ref keepTrack, ref isStartGroup))
                    {
                        if (isStartGroup)
                        {
                            group = parser;
                        }
                        else
                        {
                            acceptedParsers.Add(parser);
                        }
                    }
                    else
                    {
                        if (parser.Done && parser.Validate())
                        {
                            if (groups.Count > 0)
                            {
                                groups.Peek().LastSuccess = parser;
                            }
                            var nextParsers = parser.GetNextParsers(c);
                            foreach (var nextParser in nextParsers)
                            {
                                if (nextParser.Accept(c, 0, reader.CurrentIndex, ref keepTrack, ref isStartGroup))
                                {
                                    if (isStartGroup)
                                    {
                                        group = nextParser;
                                    }
                                    else
                                    {
                                        acceptedParsers.Add(nextParser);
                                    }
                                }
                            }
                        }
                    }

                    if (group != null)
                    {
                        groups.Push(group);
                        acceptedParsers = group.GetNextParsers(c);
                        continue;
                    }
                }

                if (acceptedParsers.Count == 0)
                {
                    if (groups.Count > 0 && (group = groups.Pop()).Accept(c, noOfWhiteSpaceIgnored, reader.CurrentIndex, ref keepTrack, ref isStartGroup))
                    {
                        if (reader.HasNext)
                        {
                            acceptedParsers = group.GetNextParsers(c);
                        }
                        else
                        {
                            acceptedParsers.Add(group);
                        }

                        group.Body = BuildChain(group, group.LastSuccess);
                    }
                    else
                    {
                        ThrowFormatException(c, reader.CurrentIndex);
                    }
                }
            }

            Parser lastestParser = null;
            var    acceptedCount = 0;

            foreach (var acceptedParser in acceptedParsers)
            {
                acceptedParser.EndExpression();
                if (acceptedParser.Validate())
                {
                    ++acceptedCount;
                    lastestParser = acceptedParser;
                }
            }
            if (acceptedCount != 1 || groups.Count > 0)
            {
                ThrowFormatException(reader.LastChar, reader.Length - 1);
            }

            var chain = BuildChain(null, lastestParser);

            return(BuildNode(parameter, chain, arg));

            void ThrowFormatException(char c, int index) => throw new FormatException($"Incorrect syntax near '{c}', index {index}");
        }
        private static Node BuildNode(ParameterExpression param, LogicalOperatorParser parser, List <Parser> list, ref int currentIndex, BuildArgument arg)
        {
            if (parser.BuiltNode != null)
            {
                return(parser.BuiltNode);
            }
            var result = new Logicality
            {
                Left       = BuildNode(param, list[currentIndex - 1], list, ref currentIndex, arg),
                Right      = BuildNode(param, list[currentIndex + 1], list, ref currentIndex, arg),
                Operator   = GetStandardOperator(parser.Result),
                StartIndex = parser.StartIndex,
                StartChar  = parser.StartChar
            };

            parser.BuiltNode       = result;
            list[currentIndex - 1] = null;
            list[currentIndex]     = null;
            list[currentIndex + 1] = parser;
            ++currentIndex;

            return(result);
        }
        private static Node BuildNode(ParameterExpression param, PropertyParser parser, BuildArgument arg)
        {
            if (parser.BuiltNode != null)
            {
                return(parser.BuiltNode);
            }

            var result = parser.Result;

            Node builtNode;

            if (parser.IsNull)
            {
                builtNode = new Constant {
                    Value = null, StartIndex = parser.StartIndex, StartChar = parser.StartChar
                };
            }
            else if (parser.IsBoolean)
            {
                builtNode = new Constant {
                    Value = result.ToLower(), Type = typeof(bool), StartIndex = parser.StartIndex, StartChar = parser.StartChar
                };
            }
            else if (arg.VariableResolver.IsVariable(result))
            {
                builtNode = new Constant {
                    Value = result, StartIndex = parser.StartIndex, StartChar = parser.StartChar, IsVariable = true
                };
            }
            else
            {
                if (parser.IsVariable)
                {
                    arg.InvalidVariables.Add(result);
                }
                else
                {
                    arg.IsValidProperty(result);
                }

                builtNode = new Property {
                    Name = result, Param = param, StartIndex = parser.StartIndex, StartChar = parser.StartChar
                };
            }

            parser.BuiltNode = builtNode;

            return(builtNode);
        }
Beispiel #15
0
 public abstract Expression Build(BuildArgument arg);
        private static Node BuildNode(ParameterExpression param, NotOperatorParser parser, List <Parser> list, ref int currentIndex, BuildArgument arg)
        {
            if (parser.BuiltNode != null)
            {
                return(parser.BuiltNode);
            }
            var index      = currentIndex;
            var nextParser = list[++currentIndex];
            var result     = new Not {
                Node = BuildNode(param, nextParser, list, ref currentIndex, arg), StartIndex = parser.StartIndex, StartChar = '!'
            };

            list[index + 1]  = null;
            parser.BuiltNode = result;

            return(result);
        }
        private static Node BuildNode(ParameterExpression param, Parser parser, List <Parser> list, ref int currentIndex, BuildArgument arg)
        {
            switch (parser)
            {
            case StringParser sp:
                return(BuildNode(sp));

            case PropertyParser pp:
                return(BuildNode(param, pp, arg));

            case NumberParser np:
                return(BuildNode(np));

            case NotOperatorParser nop:
                return(BuildNode(param, nop, list, ref currentIndex, arg));

            case NotFunctionParser nfp:
                return(BuildNode(param, nfp, arg));

            case LogicalOperatorParser lop:
                return(BuildNode(param, lop, list, ref currentIndex, arg));

            case GroupParser gp:
                return(BuildNode(param, gp, arg));

            case ComparisonOparatorParser cop:
                return(BuildNode(param, cop, list, ref currentIndex, arg));

            case ComparisonFunctionOperatorParser cfop:
                return(BuildNode(param, cfop, list, ref currentIndex, arg));

            case ArrayParser ap:
                return(BuildNode(ap));

            default: return(null);
            }
        }