private bool TryParseBinaryOperation(List <TokenOrExpression> tokens) { BinaryOperation operation; if (tokens.Count >= 3 && IsBinaryOperator(tokens[1].Token.Type, out operation)) { // Binary expression TokenOrExpression lhs = tokens[0]; TokenType op = tokens[1].Token.Type; tokens.RemoveRange(0, 2); TryParseLeftToRight(tokens); if (tokens.Count != 1) { throw new ParseException(); } IExpression leftHandSide = Parse(lhs); IExpression rightHandSide = tokens[0].Expression; var expression = new BinaryExpression(leftHandSide, operation, rightHandSide); tokens.RemoveAt(0); tokens.Insert(0, new TokenOrExpression(expression)); return(true); } return(false); }
private bool TryParseSpecialCharsAsLiteral(List <TokenOrExpression> tokens, bool consumeItemListSeparator) { if (tokens.Count >= 1) { TokenType type = tokens[0].Token.Type; switch (type) { case TokenType.Not: case TokenType.OpenBracket: case TokenType.CloseBracket: case TokenType.Quotation: case TokenType.Arrow: tokens[0] = new TokenOrExpression(new StringLiteral(Tokenizer.ToString(type))); return(true); case TokenType.ItemListSeparator: if (consumeItemListSeparator) { tokens[0] = new TokenOrExpression( new StringLiteral(Tokenizer.ToString(type)) ); return(true); } break; case TokenType.Whitespace: tokens[0] = new TokenOrExpression(new StringLiteral(tokens[0].Token.Value)); return(true); } } return(false); }
private bool TryParseOperatorsAsLiteral(List <TokenOrExpression> tokens) { UnaryOperation unaryOperation; if (tokens.Count >= 1 && IsUnaryOperator(tokens[0].Token.Type, out unaryOperation)) { tokens[0] = new TokenOrExpression(new StringLiteral( Tokenizer.ToString(tokens[0].Token.Type) )); return(true); } BinaryOperation binaryOperation; if (tokens.Count >= 1 && IsBinaryOperator(tokens[0].Token.Type, out binaryOperation)) { tokens[0] = new TokenOrExpression(new StringLiteral( Tokenizer.ToString(tokens[0].Token.Type) )); return(true); } return(false); }
private IExpression Parse(TokenOrExpression tokenOrExpression) { if (tokenOrExpression.Expression != null) { return(tokenOrExpression.Expression); } return(Parse(tokenOrExpression.Token)); }
private bool TryParseItemListReference(List <TokenOrExpression> tokens) { if (Matches(tokens, TokenType.At, TokenType.OpenBracket, TokenType.Literal, TokenType.CloseBracket)) { TokenOrExpression name = tokens[2]; tokens.RemoveRange(0, 4); tokens.Insert(0, new TokenOrExpression(new ItemListReference(name.Token.Value))); return(true); } return(false); }
private bool TryParseLiteral(List <TokenOrExpression> tokens) { if (tokens.Count >= 1 && (tokens[0].Token.Type == TokenType.Literal)) { string value = tokens[0].Token.Value; tokens[0] = new TokenOrExpression( new StringLiteral(value)); return(true); } return(false); }
private bool TryParseOne(List <TokenOrExpression> tokens) { if (TryParseVariableReference(tokens)) { return(true); } if (TryParseItemListReference(tokens)) { return(true); } if (TryParseFunctionCall(tokens)) { return(true); } if (TryParseBinaryOperation(tokens)) { return(true); } if (TryParseUnaryOperation(tokens)) { return(true); } if (tokens.Count >= 1) { if (tokens[0].Expression != null) { return(true); } if (tokens[0].Token.Type == TokenType.Literal) { tokens[0] = new TokenOrExpression(new StringLiteral(tokens[0].Token.Value)); return(true); } } return(false); }
private bool TryParseItemListProjection(List <TokenOrExpression> tokens) { int index; if (Matches(tokens, TokenType.At, TokenType.OpenBracket, TokenType.Literal, TokenType.Whitespace, TokenType.Arrow, TokenType.Whitespace) && TryFindClosingBracket(tokens, out index)) { TokenOrExpression name = tokens[2]; List <TokenOrExpression> content = tokens.Splice(6, index - 6); content.Trim(TokenType.Whitespace); content.Trim(TokenType.Quotation); tokens.RemoveRange(0, index + 1); bool parsed; do { parsed = false; if (TryParseOneConcatenationContent(content, consumeItemListSeparator: false, includeMetadataReference: true)) { parsed = true; } if (TryParseConcatenation(content, consumeItemListSeparator: false, includeMetadataReference: true)) { parsed = true; } } while (parsed && content.Count > 1); if (content.Count != 1 || content[0].Expression == null) { throw new ParseException(); } IExpression projectionRule = content[0].Expression; tokens.Insert(0, new TokenOrExpression(new ItemListProjection( name.Token.Value, projectionRule ))); return(true); } return(false); }
private bool TryParseConcatenation(List <TokenOrExpression> tokens, bool consumeItemListSeparator, bool includeMetadataReference) { Func <TokenOrExpression, bool> isLiteralOrVariable = (pair) => { if (pair.Expression is StringLiteral) { return(true); } if (pair.Expression is ItemListReference) { return(true); } if (pair.Expression is PropertyReference) { return(true); } if (pair.Expression is ConcatExpression) { return(true); } if (pair.Expression is MetadataReference) { return(includeMetadataReference); } switch (pair.Token.Type) { case TokenType.Equals: case TokenType.NotEquals: case TokenType.And: case TokenType.Or: case TokenType.GreaterThan: case TokenType.GreaterOrEquals: case TokenType.LessThan: case TokenType.LessOrEquals: case TokenType.Literal: case TokenType.Not: case TokenType.OpenBracket: case TokenType.CloseBracket: case TokenType.Quotation: case TokenType.Whitespace: return(true); case TokenType.Percent: return(includeMetadataReference); case TokenType.ItemListSeparator: return(consumeItemListSeparator); } return(false); }; if (tokens.Count >= 2 && isLiteralOrVariable(tokens[0]) && (consumeItemListSeparator || tokens[1].Token.Type != TokenType.ItemListSeparator)) { List <TokenOrExpression> lhs = tokens.Cut(0, 1); if (!TryParseOneConcatenationContent(lhs, consumeItemListSeparator, includeMetadataReference)) { throw new ParseException("Internal error"); } IExpression leftHandSide = lhs[0].Expression; if (!TryParseOneConcatenationContent(tokens, consumeItemListSeparator, includeMetadataReference)) { throw new ParseException("Internal error"); } IExpression rightHandSide = tokens[0].Expression; tokens[0] = new TokenOrExpression( new ConcatExpression(leftHandSide, rightHandSide)); return(true); } return(false); }
private IExpression Parse(IEnumerable <Token> tokens) { var stack = new List <TokenOrExpression>(); int highestPrecedence = 0; IEnumerator <Token> iterator = tokens.GetEnumerator(); while (iterator.MoveNext()) { Token token = iterator.Current; if (token.Type == TokenType.Whitespace) { continue; } if (IsOperator(token.Type)) { int precedence = Precedence(token.Type); if (precedence < highestPrecedence) { TryParseLeftToRight(stack); } stack.Add(token); highestPrecedence = precedence; } else if (token.Type == TokenType.Quotation) { // Consume everything until the quote closes again... var content = new List <TokenOrExpression>(); var arguments = new List <IExpression>(); while (iterator.MoveNext() && iterator.Current.Type != TokenType.Quotation) { content.Add(iterator.Current); if (TryParseLeftToRight(content)) { arguments.Add(content[0].Expression); content.Clear(); } } if (content.Count != 0) { throw new ParseException(); } stack.Add(new TokenOrExpression(new ConcatExpression(arguments))); } else { stack.Add(token); } } if (stack.Count == 0) { return(null); } if (!TryParseLeftToRight(stack)) { throw new ParseException(); } TokenOrExpression tok = stack[0]; return(tok.Expression); }