tree-sitter / tree-sitter-c

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

bug: wrongly parsing `#define` when the right side of the definition is empty #212

Open abougouffa opened 1 month ago

abougouffa commented 1 month ago

Did you check existing issues?

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

0.22.6

Describe the bug

The AST for C code with empty right side #define gets parsed incorrectly when a space or more is placed after.

Steps To Reproduce/Bad Parse Tree

In the code below, add a space after the second #define id(x)

(translation_unit
 (preproc_include #include path: (system_lib_string))
 (preproc_ifdef #ifdef name: (identifier)
  (preproc_function_def #define name: (identifier)
   parameters: (preproc_params ( (identifier) ))
   value: (preproc_arg))
  alternative: 
   (preproc_else #else
    (preproc_function_def #define name: (identifier)
     parameters: (preproc_params ( (identifier) ))
     value: (preproc_arg))
    (function_definition type: (primitive_type)
     declarator: 
      (function_declarator declarator: (identifier)
       parameters: (parameter_list ( )))
     body: 
      (compound_statement {
       (return_statement return (number_literal) ;)
       })))
  alternative: #endif))

Expected Behavior/Parse Tree

(translation_unit
 (preproc_include #include path: (system_lib_string))
 (preproc_ifdef #ifdef name: (identifier)
  (preproc_function_def #define name: (identifier)
   parameters: (preproc_params ( (identifier) ))
   value: (preproc_arg))
  alternative: 
   (preproc_else #else
    (preproc_function_def #define name: (identifier)
     parameters: (preproc_params ( (identifier) ))))
  #endif)
 (function_definition type: (primitive_type)
  declarator: 
   (function_declarator declarator: (identifier)
    parameters: (parameter_list ( )))
  body: 
   (compound_statement {
    (return_statement return (number_literal) ;)
    })))

Repro

#include <stdio.h>

#ifdef ID
#define id(x)    (x)
#else
#define id(x)    
#endif

int main() {
  return 0;
}