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)); }
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)); }
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)); }
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); }
internal static SearchExpression Parse(SearchExpressionParserArgs args) { return(ParserManager.Parse(args)); }