private static State ParseAfterMember(Reader r, IList<ExpressionNode> nodes) { if (ParseMemberAccessor(r)) { return State.BeforeMember; } else if (ParseStreamOperator(r)) { nodes.Add(new StreamNode()); return State.AfterMember; } else { var args = ArgumentListParser.Parse(r, '[', ']'); if (args != null) { if (args.Count == 0) { throw new ExpressionParseException(r.Position, "Indexer may not be empty."); } nodes.Add(new IndexerNode(args)); return State.AfterMember; } } return State.End; }
public static IList<string> Parse(Reader r, char open, char close) { if (r.Peek == open) { var result = new List<string>(); r.Take(); while (!r.End) { var builder = new StringBuilder(); while (!r.End && r.Peek != ',' && r.Peek != close && !char.IsWhiteSpace(r.Peek)) { builder.Append(r.Take()); } if (builder.Length == 0) { throw new ExpressionParseException(r.Position, "Expected indexer argument."); } result.Add(builder.ToString()); r.SkipWhitespace(); if (r.End) { throw new ExpressionParseException(r.Position, "Expected ','."); } else if (r.TakeIf(close)) { return result; } else { if (r.Take() != ',') { throw new ExpressionParseException(r.Position, "Expected ','."); } r.SkipWhitespace(); } } if (!r.End) { r.Take(); return result; } else { throw new ExpressionParseException(r.Position, "Expected ']'."); } } return null; }
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; } }
public static ExpressionNode Build(string expression, bool enableValidation = false) { if (string.IsNullOrWhiteSpace(expression)) { throw new ArgumentException("'expression' may not be empty."); } var reader = new Reader(expression); var parser = new ExpressionParser(enableValidation); var node = parser.Parse(reader); if (!reader.End) { throw new ExpressionParseException(reader.Position, "Expected end of expression."); } return node; }
public 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; case State.AttachedProperty: state = ParseAttachedProperty(r, nodes); break; } } if (state == State.BeforeMember) { throw new ExpressionParseException(r.Position, "Unexpected end of expression."); } for (int n = 0; n < nodes.Count - 1; ++n) { nodes[n].Next = nodes[n + 1]; } return nodes.FirstOrDefault(); }
private State ParseStart(Reader r, IList<ExpressionNode> nodes) { if (ParseNot(r)) { nodes.Add(new LogicalNotNode()); return State.Start; } else if (ParseOpenBrace(r)) { return State.AttachedProperty; } else { var identifier = IdentifierParser.Parse(r); if (identifier != null) { nodes.Add(new PropertyAccessorNode(identifier, _enableValidation)); return State.AfterMember; } } return State.End; }
private static bool ParseOpenBrace(Reader r) { return !r.End && r.TakeIf('('); }
private static bool ParseMemberAccessor(Reader r) { return !r.End && r.TakeIf('.'); }
private static bool ParseNot(Reader r) { return !r.End && r.TakeIf('!'); }
private State ParseAttachedProperty(Reader r, List<ExpressionNode> nodes) { var owner = IdentifierParser.Parse(r); if (r.End || !r.TakeIf('.')) { throw new ExpressionParseException(r.Position, "Invalid attached property name."); } var name = IdentifierParser.Parse(r); if (r.End || !r.TakeIf(')')) { throw new ExpressionParseException(r.Position, "Expected ')'."); } nodes.Add(new PropertyAccessorNode(owner + '.' + name, _enableValidation)); return State.AfterMember; }
private static bool ParseStreamOperator(Reader r) { return !r.End && r.TakeIf('^'); }