public static StringSegment ParseConditionExpression(this StringSegment literal, out ConditionExpression expr) { BooleanExpression rootExpr = null; BinaryExpression lhsBinaryExpr = null, rhsBinaryExpr = null; literal = literal.AdvancePastWhitespace(); while (!literal.IsNullOrEmpty()) { literal = literal.ParseBinaryExpression(out lhsBinaryExpr); literal = literal.AdvancePastWhitespace(); if (literal.IsNullOrEmpty() && rootExpr == null) { expr = lhsBinaryExpr; return(literal); } literal = literal.ParseNextToken(out object value, out JsBinding andOrToken); if (andOrToken == null || !andOrToken.Binding.Equals(BooleanExpression.OrKeyword) && !andOrToken.Binding.Equals(BooleanExpression.AndKeyword)) { throw new NotSupportedException($"Invalid sytnax: Expected 'and', 'or' keywords but found instead '{value ?? andOrToken}', near '{literal.SubstringWithElipsis(0,50)}'"); } var isOr = andOrToken.Binding.Equals(BooleanExpression.OrKeyword); literal = literal.ParseBinaryExpression(out rhsBinaryExpr); if (rootExpr == null) { rootExpr = isOr ? (BooleanExpression) new OrExpression(lhsBinaryExpr) : new AndExpression(lhsBinaryExpr); } if (rootExpr.MatchesBinding(andOrToken)) { rootExpr.Expressions.Add(rhsBinaryExpr); } else { rootExpr = isOr ? (BooleanExpression) new OrExpression(rootExpr, rhsBinaryExpr) : new AndExpression(rootExpr, rhsBinaryExpr); } } expr = rootExpr; return(literal); }
public static StringSegment ParseConditionExpression(this string literal, out ConditionExpression expr) => literal.ToStringSegment().ParseConditionExpression(out expr);