Beispiel #1
0
        internal static SearchExpression QueryParser(SearchExpressionParserArgs args)
        {
            var text = ParserUtils.SimplifyExpression(args.text);
            var nestedExpressions         = new List <SearchExpression>();
            var expressionsStartAndLength = ParserUtils.GetExpressionsStartAndLength(text, out _);
            var lastExpressionEndIndex    = 0;

            foreach (var expression in expressionsStartAndLength)
            {
                string exprName = string.Empty;
                if (expression[0] == '{')
                {
                    var namedText = text.Substring(lastExpressionEndIndex, expression.startIndex - text.startIndex + 1 - lastExpressionEndIndex).ToString();
                    var match     = ParserUtils.namedExpressionStartRegex.Match(namedText);
                    if (match != null && match.Success && match.Groups["name"].Value != string.Empty)
                    {
                        exprName = match.Groups["name"].Value;
                    }
                }

                var paramText        = args.With(text.Substring(expression.startIndex - text.startIndex - exprName.Length, expression.length + exprName.Length));
                var nestedExpression = ParserManager.Parse(paramText);
                nestedExpressions.Add(nestedExpression);
                lastExpressionEndIndex = expression.startIndex + expression.length;
            }

            return(new SearchExpression(SearchExpressionType.QueryString, args.text, text, QueryEvaluator, nestedExpressions.ToArray()));
        }
        internal static SearchExpression ExpressionSetParser(SearchExpressionParserArgs args)
        {
            var outerText = args.text;

            if (outerText.length < 2)
            {
                return(null);
            }
            var innerText = ParserUtils.SimplifyExpression(outerText, false);

            if (outerText.length == innerText.length)
            {
                return(null);
            }
            var text = outerText.Substring(innerText.startIndex - outerText.startIndex - 1, innerText.length + 2);

            if (text[0] != '{' || text[text.length - 1] != '}')
            {
                return(null);
            }

            var expressions = ParserUtils.GetExpressionsStartAndLength(innerText, out var rootHasParameters);

            if (!rootHasParameters)
            {
                return(null);
            }

            var parameters = ParserUtils.ExtractArguments(text)
                             .Select(paramText => ParserManager.Parse(args.With(paramText).Without(SearchExpressionParserFlags.ImplicitLiterals)))
                             .ToArray();

            return(new SearchExpression(SearchExpressionType.Set, outerText, innerText.Trim(), SetEvaluator, parameters));
        }
Beispiel #3
0
        internal static SearchExpression AliasParser(SearchExpressionParserArgs args)
        {
            // Make sure the expression contains at least the keyword `as`
            if (!args.text.Contains("as"))
            {
                return(null);
            }

            var m = s_AliasWithQuotesRx.Match(args.text.ToString());

            if (!m.Success)
            {
                m = s_AliasWithoutQuotesRx.Match(args.text.ToString());
            }

            if (!m.Success || m.Groups.Count != 2)
            {
                return(null);
            }

            var aliasGroup      = m.Groups["alias"];
            var alias           = args.text.Substring(aliasGroup.Index, aliasGroup.Length).Trim();
            var aliasExpression = ParserManager.Parse(args.With(alias).With(SearchExpressionParserFlags.ImplicitLiterals));

            var exprText       = args.text.Substring(0, m.Index);
            var expression     = ParserManager.Parse(args.With(exprText));
            var isDynamicAlias = !aliasExpression.types.HasFlag(SearchExpressionType.Text) || alias.Contains('@') || alias.Contains('$');

            if (isDynamicAlias && !string.Equals(expression.name, "alias", System.StringComparison.OrdinalIgnoreCase))
            {
                return(expression.Apply("alias", aliasExpression));
            }

            return(new SearchExpression(expression.types, args.text, expression.innerText, alias, expression.evaluator, expression.parameters));
        }
        internal static SearchExpression ImplicitStringParser(SearchExpressionParserArgs args)
        {
            if (!args.HasOption(SearchExpressionParserFlags.ImplicitLiterals))
            {
                return(null);
            }

            var text = args.text;

            if (text.length > 2)
            {
                if (ParserUtils.IsQuote(text[0]))
                {
                    if (text[0] == text[text.length - 1])
                    {
                        return(null);
                    }
                }
                if (ParserUtils.IsOpener(text[0]) && ParserUtils.IsCloser(text[text.length - 1]))
                {
                    return(null);
                }
            }

            return(new SearchExpression(SearchExpressionType.Text, text, text, ConstantEvaluator));
        }
Beispiel #5
0
        internal static SearchExpression NamedParser(SearchExpressionParserArgs args)
        {
            var text = ParserUtils.SimplifyExpression(args.text);

            if (text.IsNullOrEmpty())
            {
                return(null);
            }

            var match = ParserUtils.namedExpressionStartRegex.Match(text.ToString());

            if (!match.Success || match.Index != 0 || match.Groups["name"].Length == 0)
            {
                return(null);
            }

            var expressionsStartAndLength = ParserUtils.GetExpressionsStartAndLength(text, out _);

            if (expressionsStartAndLength.Length != 1)
            {
                return(null);
            }

            var expressionName = match.Groups["name"].Value;

            if ((expressionName.Length + expressionsStartAndLength[0].length) != text.length)
            {
                return(null);
            }

            var evaluator           = EvaluatorManager.GetEvaluatorByNameDuringParsing(expressionName, text.Substring(0, expressionName.Length));
            var parametersText      = text.Substring(expressionName.Length, text.length - expressionName.Length);
            var parametersPositions = ParserUtils.ExtractArguments(parametersText, expressionName);
            var parameters          = new List <SearchExpression>();

            var argsWith    = SearchExpressionParserFlags.None;
            var argsWithout = SearchExpressionParserFlags.ImplicitLiterals;

            ApplyEvaluatorHints(evaluator.hints, ref argsWith, ref argsWithout);
            foreach (var paramText in parametersPositions)
            {
                parameters.Add(ParserManager.Parse(args.With(paramText, argsWith).Without(argsWithout)));
            }

            if (!evaluator.hints.HasFlag(SearchExpressionEvaluationHints.DoNotValidateSignature) &&
                args.HasOption(SearchExpressionParserFlags.ValidateSignature))
            {
                var signatures = EvaluatorManager.GetSignaturesByName(expressionName);
                if (signatures != null)
                {
                    SearchExpressionValidator.ValidateExpressionArguments(evaluator, parameters.ToArray(), signatures, text);
                }
            }

            var expressionText = ParserUtils.SimplifyExpression(expressionsStartAndLength[0].Substring(1, expressionsStartAndLength[0].length - 2));

            return(new SearchExpression(SearchExpressionType.Function, args.text, expressionText, evaluator, parameters.ToArray()));
        }
        internal static SearchExpression KeywordParser(SearchExpressionParserArgs args)
        {
            foreach (var enumValue in Enum.GetNames(typeof(SearchExpressionKeyword)))
            {
                if (args.text.Equals(enumValue, StringComparison.OrdinalIgnoreCase))
                {
                    return(new SearchExpression(SearchExpressionType.Keyword, args.text, ConstantEvaluator));
                }
            }

            return(null);
        }
        public static SearchExpression Parse(SearchExpressionParserArgs args)
        {
            foreach (var parser in parsers)
            {
                var expr = parser.handler(args);
                if (expr != null)
                {
                    return(expr);
                }
            }

            throw new SearchExpressionParseException($"Expression `{args.text}` cannot be parsed.\n" +
                                                     $"{string.Join("\n", args.context.GetAllErrors().Select(e => e.reason))}".Trim(), args.text.startIndex, args.text.length);
        }
        internal static SearchExpression ExplicitStringParser(SearchExpressionParserArgs args)
        {
            var outerText = args.text;
            var text      = ParserUtils.SimplifyExpression(outerText);

            if (text.length < 2 || !ParserUtils.HasQuotes(text))
            {
                return(null);
            }

            // Check for any string, since enclosed strings are not allowed, if we find a string token that means there are multiple strings in the text
            for (int i = 1; i < text.length - 2; ++i)
            {
                if (ParserUtils.IsQuote(text[i]))
                {
                    return(null);
                }
            }
            return(new SearchExpression(SearchExpressionType.Text, outerText, text.Substring(1, text.length - 2), ConstantEvaluator));
        }
        internal static SearchExpression FixedSetParser(SearchExpressionParserArgs args)
        {
            var outerText = args.text;
            var text      = ParserUtils.SimplifyExpression(outerText);

            if (text.length < 2 || text[0] != '[' || text[text.length - 1] != ']')
            {
                return(null);
            }
            var expressions = ParserUtils.GetExpressionsStartAndLength(text, out _);

            if (expressions.Length != 1 || expressions[0].startIndex != text.startIndex || expressions[0].length != text.length)
            {
                return(null);
            }

            var parameters = ParserUtils.ExtractArguments(text)
                             .Select(paramText => ParserManager.Parse(args.With(paramText).With(SearchExpressionParserFlags.ImplicitLiterals)))
                             .ToArray();

            var innerText = ParserUtils.SimplifyExpression(text.Substring(1, text.length - 2));

            return(new SearchExpression(SearchExpressionType.Set, outerText, innerText, SetEvaluator, parameters));
        }
Beispiel #10
0
        public static bool TryParse(StringView text, out QueryMarker marker)
        {
            marker = none;
            if (!IsQueryMarker(text))
            {
                return(false);
            }

            var innerText = text.Substring(k_StartToken.Length, text.Length - k_StartToken.Length - k_EndToken.Length);

            var indexOfColon = innerText.IndexOf(':');

            if (indexOfColon < 0)
            {
                return(false);
            }

            var controlType     = innerText.Substring(0, indexOfColon).Trim().ToString();
            var args            = new List <StringView>();
            var level           = 0;
            var currentArgStart = indexOfColon + 1;

            for (var i = currentArgStart; i < innerText.Length; ++i)
            {
                if (ParserUtils.IsOpener(innerText[i]))
                {
                    ++level;
                }
                if (ParserUtils.IsCloser(innerText[i]))
                {
                    --level;
                }
                if (innerText[i] != ',' || level != 0)
                {
                    continue;
                }
                if (i + 1 == innerText.Length)
                {
                    return(false);
                }

                args.Add(innerText.Substring(currentArgStart, i - currentArgStart).Trim());
                currentArgStart = i + 1;
            }

            if (currentArgStart == innerText.Length)
            {
                return(false); // No arguments
            }
            // Extract the final argument, since there is no comma after the last argument
            args.Add(innerText.Substring(currentArgStart, innerText.Length - currentArgStart).Trim());

            var queryMarkerArguments = new List <QueryMarkerArgument>();

            using (var context = SearchService.CreateContext(""))
            {
                foreach (var arg in args)
                {
                    var parserArgs = new SearchExpressionParserArgs(arg, context, SearchExpressionParserFlags.ImplicitLiterals);
                    SearchExpression expression = null;
                    try
                    {
                        expression = SearchExpression.Parse(parserArgs);
                    }
                    catch (SearchExpressionParseException)
                    { }

                    if (expression == null || !expression.types.HasAny(SearchExpressionType.Literal))
                    {
                        queryMarkerArguments.Add(new QueryMarkerArgument {
                            rawText = arg, expression = expression, value = expression == null ? arg.ToString() : null
                        });
                        continue;
                    }
                    var results             = expression.Execute(context);
                    var resolvedValue       = results.FirstOrDefault(item => item != null);
                    var resolvedValueObject = resolvedValue?.value;
                    queryMarkerArguments.Add(new QueryMarkerArgument {
                        rawText = arg, expression = expression, value = resolvedValueObject
                    });
                }
            }

            marker = new QueryMarker {
                type = controlType, text = text, args = queryMarkerArguments.ToArray()
            };
            return(true);
        }
Beispiel #11
0
 internal static SearchExpression Parse(SearchExpressionParserArgs args)
 {
     return(ParserManager.Parse(args));
 }