private ExpressionSyntax ParseSubExpression(ExpressionSyntax left, int precedence) { if (left == null) { // No left operand, so we parse one and take care of leading unary operators var unaryExpression = SyntaxFacts.GetUnaryOperatorExpression(Current.Kind); left = unaryExpression == SyntaxKind.BadToken ? ParseSimpleExpression() : ParseUnaryExpression(unaryExpression); } while (Current.Kind != SyntaxKind.EndOfFileToken) { // Special handling for NOT BETWEEN, NOT IN, NOT LIKE, NOT SIMILAR TO, and NOT SOUND SLIKE. var notKeyword = Current.Kind == SyntaxKind.NotKeyword && Lookahead.Kind.CanHaveLeadingNot() ? NextToken() : null; // Special handling for the only ternary operator BETWEEN if (Current.Kind == SyntaxKind.BetweenKeyword) { var operatorPrecedence = SyntaxFacts.GetTernaryOperatorPrecedence(SyntaxKind.BetweenExpression); if (operatorPrecedence <= precedence) { return(left); } left = ParseBetweenExpression(left, notKeyword); } else { // If there is no binary operator we are finished var binaryExpression = SyntaxFacts.GetBinaryOperatorExpression(Current.Kind); if (binaryExpression == SyntaxKind.BadToken) { return(left); } var operatorPrecedence = SyntaxFacts.GetBinaryOperatorPrecedence(binaryExpression); // Precedence is lower or equal, parse it later if (operatorPrecedence <= precedence) { return(left); } // Precedence is higher left = ParseBinaryExpression(left, notKeyword, binaryExpression, operatorPrecedence); } } return(left); }
private BoundExpression BindAllAnySubselect(AllAnySubselectSyntax node) { var expressionKind = SyntaxFacts.GetBinaryOperatorExpression(node.OperatorToken.Kind); var operatorKind = expressionKind.ToBinaryOperatorKind(); var isAll = node.Keyword.Kind == SyntaxKind.AllKeyword; return(BindAllAnySubselect(node.Span, node.Left, isAll, node.Query, operatorKind)); }