public void Parse_BinaryExpression_HonorsPrecedences(SyntaxKind op1, SyntaxKind op2) { //Arrange var op1Precedence = SyntaxFacts.GetBinaryOperatorPrecedence(op1); var op2Precedence = SyntaxFacts.GetBinaryOperatorPrecedence(op2); var op1Text = SyntaxFacts.GetText(op1); var op2Text = SyntaxFacts.GetText(op2); var text = $"a {op1Text} b {op2Text} c"; var expression = ParseExpression(text); if (op1Precedence >= op2Precedence) { /* * op2 * / \ * op1 c * / \ * a b */ using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(op1, op1Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); e.AssertToken(op2, op2Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } else { /* * op1 * / \ * a op2 * / \ * b c */ using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(op1, op1Text); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); e.AssertToken(op2, op2Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } }
public void Parser_BinaryExpression_honors_precedences(SyntaxKind op1, SyntaxKind op2) { var op1Precendence = SyntaxFacts.GetBinaryOperatorPrecedence(op1); var op2Precendence = SyntaxFacts.GetBinaryOperatorPrecedence(op2); var op1Text = SyntaxFacts.GetText(op1); var op2Text = SyntaxFacts.GetText(op2); var text = $"a {op1Text} b {op2Text} c"; var expression = ParseExpression(text); if (op1Precendence >= op2Precendence) { // op2 // / \ // op1 c // / \ // a b using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(op1, op1Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); e.AssertToken(op2, op2Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } else { // op1 // / \ // a op2 // / \ // b c using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(op1, op1Text); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); e.AssertToken(op2, op2Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } }
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); }
public void Parse_UnaryExpression_HonorsPrecedences(SyntaxKind unaryKind, SyntaxKind binaryKind) { //Arrange var unaryPrecedence = SyntaxFacts.GetUnaryOperatorPrecedence(unaryKind); var binaryPrecedence = SyntaxFacts.GetBinaryOperatorPrecedence(binaryKind); var unaryText = SyntaxFacts.GetText(unaryKind); var binaryText = SyntaxFacts.GetText(binaryKind); var text = $"{unaryText} a {binaryText} b"; var expression = ParseExpression(text); if (unaryPrecedence >= binaryPrecedence) { /* * binary * / \ * unary b | | a */ using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.UnaryExpression); e.AssertToken(unaryKind, unaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(binaryKind, binaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); } } else { /* * unary | | binary | / \ | a b */ using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.UnaryExpression); e.AssertToken(unaryKind, unaryText); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(binaryKind, binaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); } } }
public void Parser_UnaryExpression_honors_precedences(SyntaxKind unaryKind, SyntaxKind binaryKind) { var unaryPrecendence = SyntaxFacts.GetUnaryOperatorPrecedence(unaryKind); var binaryPrecendence = SyntaxFacts.GetBinaryOperatorPrecedence(binaryKind); var unaryText = SyntaxFacts.GetText(unaryKind); var binaryText = SyntaxFacts.GetText(binaryKind); var text = $"{unaryText} a {binaryText} b"; var expression = ParseExpression(text); if (unaryPrecendence >= binaryPrecendence) { // binary // / \ // unary b // | // a using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.UnaryExpression); e.AssertToken(unaryKind, unaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(binaryKind, binaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); } } else { // unary // | // binary // / \ // a b using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.UnaryExpression); e.AssertToken(unaryKind, unaryText); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(binaryKind, binaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); } } }
private static void WriteBinaryExpression(BoundBinaryExpression node, IndentedTextWriter writer) { var precedence = SyntaxFacts.GetBinaryOperatorPrecedence(node.Operator.SyntaxKind); writer.WriteNestedExpression(precedence, node.Left); writer.WriteSpace(); writer.WritePunctuation(node.Operator.SyntaxKind); writer.WriteSpace(); writer.WriteNestedExpression(precedence, node.Right); }
private ExpressionSyntax ParseBetweenExpression(ExpressionSyntax left, SyntaxToken notKeyword) { var andPrecedence = SyntaxFacts.GetBinaryOperatorPrecedence(SyntaxKind.LogicalAndExpression); var betweenKeyword = NextToken(); var lowerBound = ParseSubExpression(null, andPrecedence); var andKeyword = Match(SyntaxKind.AndKeyword); var upperBound = ParseSubExpression(null, andPrecedence); return(new BetweenExpressionSyntax(_syntaxTree, left, notKeyword, betweenKeyword, lowerBound, andKeyword, upperBound)); }
private static void WriteNestedExpression(this IndentedTextWriter writer, int parentPrecedence, BoundExpression expression) { if (expression is BoundUnaryExpression unary) { writer.WriteNestedExpression(parentPrecedence, SyntaxFacts.GetUnaryOperatorPrecedence(unary.Operator.SyntaxKind), unary); } else if (expression is BoundBinaryExpression binary) { writer.WriteNestedExpression(parentPrecedence, SyntaxFacts.GetBinaryOperatorPrecedence(binary.Operator.SyntaxKind), binary); } else { expression.WriteTo(writer); } }
private static bool LeftBindsStrongerThanRight(SyntaxKind leftKind, SyntaxKind rightKind) { var leftPrecedence = SyntaxFacts.GetBinaryOperatorPrecedence(leftKind); var rightPrecedence = SyntaxFacts.GetBinaryOperatorPrecedence(rightKind); if (leftPrecedence > rightPrecedence) { return(true); } if (leftPrecedence == rightPrecedence && !SyntaxFacts.IsRightAssociative(leftKind)) { return(true); } return(false); }
public void Parser_UnaryExpression_HonorsPrecedences(SyntaxKind op1, SyntaxKind op2) { var op1Precedence = SyntaxFacts.GetUnaryOperatorPrecedence(op1); var op2Precedence = SyntaxFacts.GetBinaryOperatorPrecedence(op2); var op1Text = SyntaxFacts.GetText(op1); var op2Text = SyntaxFacts.GetText(op2); var text = $"{op1Text} b {op2Text} c"; var expression = ParseExpression(text); if (op1Precedence >= op2Precedence) { /* * └───BinaryExpression * ├───UnaryExpression * │ ├───MinusToken * │ └───NameExpression * │ └───IndentifierToken * ├───StarToken * └───NameExpression * └───IndentifierToken */ using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.UnaryExpression); e.AssertToken(op1, op1Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); e.AssertToken(op2, op2Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } else { using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.UnaryExpression); e.AssertToken(op1, op1Text); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); e.AssertToken(op2, op2Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } }
public void Parser_BinaryExpression_HonorsPrecedences(SyntaxKind op1, SyntaxKind op2) { var op1Precedence = SyntaxFacts.GetBinaryOperatorPrecedence(op1); var op2Precedence = SyntaxFacts.GetBinaryOperatorPrecedence(op2); var op1Text = SyntaxFacts.GetText(op1); var op2Text = SyntaxFacts.GetText(op2); var text = $"a {op1Text} b {op2Text} c"; var expression = SyntaxTree.Parse(text).Root; if (op1Precedence >= op2Precedence) { using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(op1, op1Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); e.AssertToken(op2, op2Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } else { using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(op1, op1Text); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); e.AssertToken(op2, op2Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } }
public void Parser_UnaryExpression_HonorsPrecedences(SyntaxKind unaryKind, SyntaxKind binaryKind) { var unaryPrecedence = SyntaxFacts.GetUnaryOperatorPrecedence(unaryKind); var binaryPrecedence = SyntaxFacts.GetBinaryOperatorPrecedence(binaryKind); var unaryText = SyntaxFacts.GetText(unaryKind); var binaryText = SyntaxFacts.GetText(binaryKind); var text = $"{unaryText} a {binaryText} b"; var expression = SyntaxTree.Parse(text).Root; if (unaryPrecedence >= binaryPrecedence) { using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.UnaryExpression); e.AssertToken(unaryKind, unaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(binaryKind, binaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); } } else { using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.UnaryExpression); e.AssertToken(unaryKind, unaryText); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(binaryKind, binaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); } } }
public void Parser_BinaryExpression_HonoursPrecedences(SyntaxKind _op1, SyntaxKind _op2) { var _op1Precedence = SyntaxFacts.GetBinaryOperatorPrecedence(_op1); var _op2Precedence = SyntaxFacts.GetBinaryOperatorPrecedence(_op2); var _op1Text = SyntaxFacts.GetText(_op1); var _op2Text = SyntaxFacts.GetText(_op2); var _text = $"a {_op1Text} b {_op2Text} c"; var _expression = ParseExpression(_text); if (_op1Precedence >= _op2Precedence) { using (var _e = new AssertingEnumerator(_expression)) { _e.AssertNode(SyntaxKind.BinaryExpression); _e.AssertNode(SyntaxKind.BinaryExpression); _e.AssertNode(SyntaxKind.NameExpression); _e.AssertToken(SyntaxKind.IdentifierToken, "a"); _e.AssertToken(_op1, _op1Text); _e.AssertNode(SyntaxKind.NameExpression); _e.AssertToken(SyntaxKind.IdentifierToken, "b"); _e.AssertToken(_op2, _op2Text); _e.AssertNode(SyntaxKind.NameExpression); _e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } else { using (var _e = new AssertingEnumerator(_expression)) { _e.AssertNode(SyntaxKind.BinaryExpression); _e.AssertNode(SyntaxKind.NameExpression); _e.AssertToken(SyntaxKind.IdentifierToken, "a"); _e.AssertToken(_op1, _op1Text); _e.AssertNode(SyntaxKind.BinaryExpression); _e.AssertNode(SyntaxKind.NameExpression); _e.AssertToken(SyntaxKind.IdentifierToken, "b"); _e.AssertToken(_op2, _op2Text); _e.AssertNode(SyntaxKind.NameExpression); _e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } }
public void ParserBinaryExpressionHonornsPrecedences(SyntaxKind op1, SyntaxKind op2) { int op1Precedence = SyntaxFacts.GetBinaryOperatorPrecedence(op1); int op2Precedence = SyntaxFacts.GetBinaryOperatorPrecedence(op2); string op1Text = SyntaxFacts.GetText(op1); string op2Text = SyntaxFacts.GetText(op2); string text = $"a {op1Text} b {op2Text} c"; ExpressionSyntax expression = ParseExpression(text); if (op1Precedence >= op2Precedence) { using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(op1, op1Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); e.AssertToken(op2, op2Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } else { using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(op1, op1Text); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); e.AssertToken(op2, op2Text); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "c"); } } }
public void Parses_MultipleBinaryExpression_HonouringPrecedence(SyntaxKind left, SyntaxKind right) { var leftPrecedence = SyntaxFacts.GetBinaryOperatorPrecedence(left); var rightPrecedence = SyntaxFacts.GetBinaryOperatorPrecedence(right); var leftText = SyntaxFacts.GetText(left); var rightText = SyntaxFacts.GetText(right); var text = $"1 {leftText} 2 {rightText} 3"; if (rightPrecedence > leftPrecedence) { AssertParseTree(text, Binary( Literal(1), left, Binary( Literal(2), right, Literal(3) ) ) ); } else { AssertParseTree(text, Binary( Binary( Literal(1), left, Literal(2) ), right, Literal(3) ) ); } }
public void ParserUnaryExpressionHonornsPrecedences(SyntaxKind unaryKind, SyntaxKind binaryKind) { int unaryPrecedence = SyntaxFacts.GetUnaryOperatorPrecedence(unaryKind); int binaryPrecedence = SyntaxFacts.GetBinaryOperatorPrecedence(binaryKind); string unaryText = SyntaxFacts.GetText(unaryKind); string binaryText = SyntaxFacts.GetText(binaryKind); string text = $"{unaryText} a {binaryText} b"; ExpressionSyntax expression = ParseExpression(text); if (unaryPrecedence >= binaryPrecedence) { using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.UnaryExpression); e.AssertToken(unaryKind, unaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(binaryKind, binaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); } } else { using (var e = new AssertingEnumerator(expression)) { e.AssertNode(SyntaxKind.UnaryExpression); e.AssertToken(unaryKind, unaryText); e.AssertNode(SyntaxKind.BinaryExpression); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "a"); e.AssertToken(binaryKind, binaryText); e.AssertNode(SyntaxKind.NameExpression); e.AssertToken(SyntaxKind.IdentifierToken, "b"); } } }
public void Parser_UnaryExpression_HonoursPrecedences(SyntaxKind _unaryKind, SyntaxKind _binaryKind) { var _unaryPrecedence = SyntaxFacts.GetUnaryOperatorPrecedence(_unaryKind); var _binaryPrecedence = SyntaxFacts.GetBinaryOperatorPrecedence(_binaryKind); var _unaryText = SyntaxFacts.GetText(_unaryKind); var _binaryText = SyntaxFacts.GetText(_binaryKind); var _text = $"{_unaryText} a {_binaryText} b"; var _expression = ParseExpression(_text); if (_unaryPrecedence >= _binaryPrecedence) { using (var _e = new AssertingEnumerator(_expression)) { _e.AssertNode(SyntaxKind.BinaryExpression); _e.AssertNode(SyntaxKind.UnaryExpression); _e.AssertToken(_unaryKind, _unaryText); _e.AssertNode(SyntaxKind.NameExpression); _e.AssertToken(SyntaxKind.IdentifierToken, "a"); _e.AssertToken(_binaryKind, _binaryText); _e.AssertNode(SyntaxKind.NameExpression); _e.AssertToken(SyntaxKind.IdentifierToken, "b"); } } else { using (var _e = new AssertingEnumerator(_expression)) { _e.AssertNode(SyntaxKind.UnaryExpression); _e.AssertToken(_unaryKind, _unaryText); _e.AssertNode(SyntaxKind.BinaryExpression); _e.AssertNode(SyntaxKind.NameExpression); _e.AssertToken(SyntaxKind.IdentifierToken, "a"); _e.AssertToken(_binaryKind, _binaryText); _e.AssertNode(SyntaxKind.NameExpression); _e.AssertToken(SyntaxKind.IdentifierToken, "b"); } } }
protected override void RenderLine(string text) { var tokens = SyntaxTree.ParseTokens(text); foreach (var token in tokens) { var isKeyword = token.Kind.ToString().EndsWith("Keyword"); var isOperator = SyntaxFacts.GetBinaryOperatorPrecedence(token.Kind) > 0 || SyntaxFacts.GetUnaryOperatorPrecedence(token.Kind) > 0; var isIdentifier = token.Kind == SyntaxKind.IdentifierToken; var isNumber = token.Kind == SyntaxKind.NumberToken; var isString = token.Kind == SyntaxKind.StringToken; if (isKeyword) { Console.ForegroundColor = ConsoleColor.Blue; } else if (isIdentifier) { Console.ForegroundColor = ConsoleColor.DarkYellow; } else if (isOperator) { Console.ForegroundColor = ConsoleColor.DarkGray; } else if (isNumber) { Console.ForegroundColor = ConsoleColor.Cyan; } else if (isString) { Console.ForegroundColor = ConsoleColor.Magenta; } Console.Write(token.Text); Console.ResetColor(); } }