tree-sitter / tree-sitter-c

C grammar for tree-sitter
MIT License
225 stars 100 forks source link

bug: incorrectly parse parenthesis expression as type casting #210

Open tycheng opened 2 months ago

tycheng commented 2 months ago

Did you check existing issues?

Tree-Sitter CLI Version, if relevant (output of tree-sitter --version)

No response

Describe the bug

C style casting has very high precedence and incorrectly parse expression a < (b) && c > d. (b) is parsed to be a type-specifier, && has been parsed to two consecutive pointer-expressions, so the expression becomes (a) < ((b)&&c) > d.

However, in C/C++, taking the address of a variable twice is not possible, so this parse result is definitely wrong (no ambiguity) in this case.

Steps To Reproduce/Bad Parse Tree

See the "Repro" program.

Expected Behavior/Parse Tree

[translation_unit](https://tree-sitter.github.io/tree-sitter/playground#) [0, 0] - [4, 0]
  [function_definition](https://tree-sitter.github.io/tree-sitter/playground#) [0, 0] - [3, 1]
    type: [primitive_type](https://tree-sitter.github.io/tree-sitter/playground#) [0, 0] - [0, 4]
    declarator: [function_declarator](https://tree-sitter.github.io/tree-sitter/playground#) [0, 5] - [0, 11]
      declarator: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [0, 5] - [0, 9]
      parameters: [parameter_list](https://tree-sitter.github.io/tree-sitter/playground#) [0, 9] - [0, 11]
    body: [compound_statement](https://tree-sitter.github.io/tree-sitter/playground#) [0, 12] - [3, 1]
      [declaration](https://tree-sitter.github.io/tree-sitter/playground#) [1, 1] - [1, 16]
        type: [primitive_type](https://tree-sitter.github.io/tree-sitter/playground#) [1, 1] - [1, 4]
        declarator: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [1, 5] - [1, 6]
        declarator: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [1, 8] - [1, 9]
        declarator: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [1, 11] - [1, 12]
        declarator: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [1, 14] - [1, 15]
      [expression_statement](https://tree-sitter.github.io/tree-sitter/playground#) [2, 1] - [2, 16]
        [binary_expression](https://tree-sitter.github.io/tree-sitter/playground#) [2, 1] - [2, 15]
          left: [binary_expression](https://tree-sitter.github.io/tree-sitter/playground#) [2, 1] - [2, 6]
            left: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [2, 1] - [2, 2]
            right: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [2, 5] - [2, 6]
          right: [binary_expression](https://tree-sitter.github.io/tree-sitter/playground#) [2, 10] - [2, 15]
            left: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [2, 10] - [2, 11]
            right: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [2, 14] - [2, 15]

Repro

void main() {
    int a, b, c, d;
    a > (b) && c < d;
}