private static char ParseEscapedCharacter(ExpressionReader reader) { var c = reader.ReadChar(); switch (c) { case '\'': case '\\': return(c); case 'b': return('\b'); case 'f': return('\f'); case 'n': return('\n'); case 'r': return('\r'); case 't': return('\t'); case 'u': return(ParseUnicodeCharacter(reader)); default: throw reader.UnexpectedCharacterException(); } }
public static string Parse(ExpressionReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (reader.ReadChar() != '\'') { throw reader.UnexpectedCharacterException(); } var value = new StringBuilder(); while (reader.Peek() != -1) { var c = reader.ReadChar(); switch (c) { case '\\': value.Append(ParseEscapedCharacter(reader)); break; case '\'': return(value.ToString()); default: value.Append(c); break; } } throw reader.UnexpectedCharacterException(); }
private static string ParseDictionaryKey(ExpressionReader reader) { reader.Read(); //Skip { var key = new StringBuilder(); while (reader.Peek() != -1 && reader.PeekChar() != '}') { key.Append(reader.ReadChar()); } if (key.Length == 0) { throw reader.UnexpectedCharacterException(); } if (reader.Read() != '}') { throw reader.UnexpectedCharacterException(); } reader.SkipWhitespace(); return(key.ToString()); }
private static BooleanOperator ParseBooleanOperator(ExpressionReader reader) { var c0 = reader.ReadChar(); var c1 = reader.PeekChar(); if (c0 == '&') { if (c1 == '&') { reader.ReadChar(); } return(BooleanOperator.And); } if (c0 == '|') { if (c1 == '|') { reader.ReadChar(); } return(BooleanOperator.Or); } throw reader.UnexpectedCharacterException(); }
public static IBooleanExpression Parse(string text) { using (var reader = new ExpressionReader(text)) { return(ParseExpression(reader, BooleanOperator.And)); } }
public static char ReadChar(this ExpressionReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } return((char)reader.Read()); }
public static void SkipWhitespace(this ExpressionReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } while (char.IsWhiteSpace(reader.PeekChar())) { reader.Read(); } }
private static IBooleanExpression ParseExpression(ExpressionReader reader, BooleanOperator booleanOperator) { var expressions = ParseBooleanExpressions(reader, booleanOperator).ToArray(); if (reader.Peek() != -1) { throw reader.UnexpectedCharacterException(); } return(expressions.Length == 1 ? expressions.Single() : new GroupExpression(expressions, booleanOperator)); }
private static ComparisonExpression ParseComparison(ExpressionReader reader, BooleanOperator booleanOperator) { var left = ParseValue(reader); reader.SkipWhitespace(); var comparisonOperator = ParseOperator(reader); reader.SkipWhitespace(); var right = ParseValue(reader); return(new ComparisonExpression(left, right, comparisonOperator, booleanOperator)); }
public static Exception UnexpectedCharacterException(this ExpressionReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } var position = reader.LastAccessedPosition; return(new InvalidExpressionException( $"Unexpected character at position {position}" + Environment.NewLine + reader.OriginalText + Environment.NewLine + new string(' ', position) + '\u21D1')); }
private static string ParseVariableName(ExpressionReader reader) { var name = new StringBuilder(); while (IsNameChar(reader.PeekChar())) { name.Append(reader.ReadChar()); } if (name.Length == 0) { throw reader.UnexpectedCharacterException(); } return(name.ToString()); }
private static char ParseUnicodeCharacter(ExpressionReader reader) { var code = new StringBuilder(); for (var i = 0; i < 4; i++) { var c = reader.ReadChar(); if (!IsHexChar(c)) { throw reader.UnexpectedCharacterException(); } code.Append(c); } return((char)int.Parse(code.ToString(), NumberStyles.HexNumber)); }
private static ValueExpression ParseValue(ExpressionReader reader) { var c = reader.PeekChar(); switch (c) { case '$': return(VariableParser.ParseVariable(reader)); case '\'': return(ParseConstant(reader)); default: throw reader.UnexpectedCharacterException(); } }
private static IReadOnlyCollection <IBooleanExpression> ParseGroup(ExpressionReader reader) { reader.Read(); //Skip ( reader.SkipWhitespace(); var result = ParseBooleanExpressions(reader, BooleanOperator.And).ToArray(); reader.SkipWhitespace(); var c = reader.ReadChar(); if (c != ')') { throw reader.UnexpectedCharacterException(); } return(result); }
private static IBooleanExpression ParseExpressionPart(ExpressionReader reader, BooleanOperator booleanOperator) { reader.SkipWhitespace(); if (reader.PeekChar() != '(') { return(ParseComparison(reader, booleanOperator)); } var expressions = ParseGroup(reader); if (expressions.Count == 1) { return(EnsureOperator(expressions.Single(), booleanOperator)); } return(new GroupExpression(expressions, booleanOperator)); }
public static VariableString Parse(string text) { if (text == null) { throw new ArgumentNullException(nameof(text)); } var result = new List <object>(); var basicString = new StringBuilder(); using (var reader = new ExpressionReader(text)) { while (reader.Peek() != -1) { switch (reader.PeekChar()) { case '$': FlushString(); result.Add(VariableParser.ParseVariable(reader)); break; default: var c = reader.ReadChar(); basicString.Append(c); break; } } } FlushString(); return(new VariableString(result)); void FlushString() { if (basicString.Length <= 0) { return; } result.Add(basicString.ToString()); basicString.Clear(); } }
public static VariableExpression ParseVariable(ExpressionReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (reader.ReadChar() != '$') { throw reader.UnexpectedCharacterException(); } if (reader.ReadChar() != '(') { throw reader.UnexpectedCharacterException(); } reader.SkipWhitespace(); var name = ParseVariableName(reader); reader.SkipWhitespace(); VariableExpression variable; if (reader.PeekChar() == '{') { var dictionaryKey = ParseDictionaryKey(reader); var defaultValue = ParseDefaultValue(reader); variable = new DictionaryVariableExpression(name, dictionaryKey, defaultValue); } else { var defaultValue = ParseDefaultValue(reader); variable = new SimpleVariableExpression(name, defaultValue); } if (reader.ReadChar() != ')') { throw reader.UnexpectedCharacterException(); } return(variable); }
private static ComparisonOperator ParseOperator(ExpressionReader reader) { var c = reader.ReadChar(); if (c == '=' && reader.PeekChar() == '=') { reader.Read(); return(ComparisonOperator.Equal); } if (c == '!' && reader.PeekChar() == '=') { reader.Read(); return(ComparisonOperator.NotEqual); } if (c == '>' && reader.PeekChar() == '=') { reader.Read(); return(ComparisonOperator.GreaterThanOrEqual); } if (c == '<' && reader.PeekChar() == '=') { reader.Read(); return(ComparisonOperator.LessThanOrEqual); } if (c == '>') { return(ComparisonOperator.GreaterThan); } if (c == '<') { return(ComparisonOperator.LessThan); } throw reader.UnexpectedCharacterException(); }
private static IEnumerable <IBooleanExpression> ParseBooleanExpressions( ExpressionReader reader, BooleanOperator booleanOperator) { reader.SkipWhitespace(); yield return(ParseExpressionPart(reader, booleanOperator)); reader.SkipWhitespace(); if (reader.Peek() == -1) { yield break; } while (reader.Peek() != -1) { switch (reader.PeekChar()) { case '|': case '&': var @operator = ParseBooleanOperator(reader); reader.SkipWhitespace(); yield return(ParseExpressionPart(reader, @operator)); reader.SkipWhitespace(); break; case ')': yield break; default: throw reader.UnexpectedCharacterException(); } } if (reader.Peek() != -1) { throw reader.UnexpectedCharacterException(); } }
private static string ParseDefaultValue(ExpressionReader reader) { if (reader.PeekChar() != '|') { return(null); } reader.Read(); if (reader.PeekChar() == '\'') { return(ConstantParser.Parse(reader)); } var value = new StringBuilder(); while (IsValidDefaultChar(reader.PeekChar())) { value.Append(reader.ReadChar()); } return(value.ToString()); }
private static ConstantExpression ParseConstant(ExpressionReader reader) { var constantValue = ConstantParser.Parse(reader); return(new ConstantExpression(constantValue)); }