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));
        }
예제 #2
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);
        }
예제 #3
0
        public static QueryMarker[] ParseAllMarkers(StringView text)
        {
            if (text.Length <= k_StartToken.Length + k_EndToken.Length)
            {
                return(null);
            }

            List <QueryMarker> markers = new List <QueryMarker>();
            var  startIndex            = -1;
            var  endIndex    = -1;
            var  nestedLevel = 0;
            bool inQuotes    = false;

            for (var i = 0; i < text.Length; ++i)
            {
                if (i + k_StartToken.Length > text.Length || i + k_EndToken.Length > text.Length)
                {
                    break;
                }

                if (ParserUtils.IsOpener(text[i]) && !inQuotes)
                {
                    ++nestedLevel;
                }
                if (ParserUtils.IsCloser(text[i]) && !inQuotes)
                {
                    --nestedLevel;
                }
                if (text[i] == '"' || text[i] == '\'')
                {
                    inQuotes = !inQuotes;
                }

                if (startIndex == -1 && nestedLevel == 0 && !inQuotes)
                {
                    var openerSv = text.Substring(i, k_StartToken.Length);
                    if (openerSv == k_StartToken)
                    {
                        startIndex = i;
                    }
                }

                if (endIndex == -1 && nestedLevel == 0 && !inQuotes)
                {
                    var closerSv = text.Substring(i, k_EndToken.Length);
                    if (closerSv == k_EndToken)
                    {
                        endIndex = i + k_EndToken.Length;
                    }
                }

                if (startIndex != -1 && endIndex != -1)
                {
                    var markerSv = text.Substring(startIndex, endIndex - startIndex);
                    if (TryParse(markerSv, out var marker))
                    {
                        markers.Add(marker);
                    }
                    startIndex = -1;
                    endIndex   = -1;
                }
            }

            return(markers.ToArray());
        }