public static ExpressionNode Parse(Reader r) { var nodes = new List<ExpressionNode>(); var state = State.Start; while (!r.End && state != State.End) { switch (state) { case State.Start: state = ParseStart(r, nodes); break; case State.AfterMember: state = ParseAfterMember(r, nodes); break; case State.BeforeMember: state = ParseBeforeMember(r, nodes); break; } } if (state == State.BeforeMember) { throw new ExpressionParseException(r, "Unexpected end of expression."); } for (int n = 0; n < nodes.Count - 1; ++n) { nodes[n].Next = nodes[n + 1]; } return nodes.FirstOrDefault(); }
public static IList<object> Parse(Reader r, char open, char close) { if (r.Peek == open) { var result = new List<object>(); r.Take(); while (!r.End) { var literal = LiteralParser.Parse(r); if (literal != null) { result.Add(literal); } else { throw new ExpressionParseException(r, "Expected integer."); } r.SkipWhitespace(); if (r.End) { throw new ExpressionParseException(r, "Expected ','."); } else if (r.TakeIf(close)) { return result; } else { if (r.Take() != ',') { throw new ExpressionParseException(r, "Expected ','."); } r.SkipWhitespace(); } } if (!r.End) { r.Take(); return result; } else { throw new ExpressionParseException(r, "Expected ']'."); } } return null; }
public static ExpressionNode Build(string expression) { if (string.IsNullOrWhiteSpace(expression)) { throw new ArgumentException("'expression' may not be empty."); } var reader = new Reader(expression); var node = ExpressionParser.Parse(reader); if (!reader.End) { throw new ExpressionParseException(reader, "Expected end of expression."); } return node; }
public static string Parse(Reader r) { if (IsValidIdentifierStart(r.Peek)) { var result = new StringBuilder(); while (!r.End && IsValidIdentifierChar(r.Peek)) { result.Append(r.Take()); } return result.ToString(); } else { return null; } }
private static State ParseStart(Reader r, IList<ExpressionNode> nodes) { if (ParseNot(r)) { nodes.Add(new LogicalNotNode()); return State.Start; } else { var identifier = IdentifierParser.Parse(r); if (identifier != null) { nodes.Add(new PropertyAccessorNode(identifier)); return State.AfterMember; } } return State.End; }
public static object Parse(Reader r) { if (char.IsDigit(r.Peek)) { StringBuilder result = new StringBuilder(); while (!r.End) { if (char.IsDigit(r.Peek)) { result.Append(r.Take()); } else { break; } } return int.Parse(result.ToString(), CultureInfo.InvariantCulture); } return null; }
private static State ParseAfterMember(Reader r, IList<ExpressionNode> nodes) { if (ParseMemberAccessor(r)) { return State.BeforeMember; } else { var args = ArgumentListParser.Parse(r, '[', ']'); if (args != null) { if (args.Count == 0) { throw new ExpressionParseException(r, "Indexer may not be empty."); } nodes.Add(new IndexerNode(args)); return State.AfterMember; } } return State.End; }
internal ExpressionParseException(Reader r, string message) : this(r.Position, message) { }
private static State ParseBeforeMember(Reader r, IList<ExpressionNode> nodes) { var identifier = IdentifierParser.Parse(r); if (identifier != null) { nodes.Add(new PropertyAccessorNode(identifier)); return State.AfterMember; } return State.End; }
private static bool ParseMemberAccessor(Reader r) { return !r.End && r.TakeIf('.'); }
private static bool ParseNot(Reader r) { return !r.End && r.TakeIf('!'); }