start: top_level* ?top_level: fun_decl | global_var | fun_def | struct_def | typedef fun_decl: fun_prot ";" fun_prot: type symbol "(" [fun_param ("," fun_param)*] ")" fun_param: type [symbol] global_var: type symbol sized_array* empty_array? [ "=" literal ] ";" fun_def: fun_prot body typedef: "typedef" type IDENTIFIER ";" body: "{" statement* "}" statement: if_stat | while_stat | for_stat | do_while_stat | "break" ";" -> break | "continue" ";" -> continue | "goto" label ";" -> goto // yay \o/ | "return" expression ";" -> return_stat | local_var ";" | local_array | expression ";" | body if_stat: "if" "(" expression ")" statement ["else" statement] while_stat: "while" "(" expression ")" statement for_stat: "for" "(" local_var? ";" expression? ";" iter_expression? ")" statement do_while_stat: "do" statement "while" "(" expression ")" statement iter_expression: expression local_var: type symbol initializer? local_array: type symbol sized_array* (sized_array | empty_array) initializer? ";" empty_array: "[" "]" sized_array: "[" array_size "]" ?initializer: "=" (expression | initializer_list) initializer_list: "{" [init_list_field ("," init_list_field)* ","? ] "}" ?init_list_field: "." field "=" expression | prec14_expr // precedence from https://en.cppreference.com/w/c/language/operator_precedence ?expression: comma_expr ?comma_expr: prec14_expr | comma_expr "," prec14_expr ?prec14_expr: prec13_expr | prec2_expr "=" prec14_expr -> assignment | prec2_expr "+=" prec14_expr -> add_ass | prec2_expr "-=" prec14_expr | prec2_expr "*=" prec14_expr | prec2_expr "/=" prec14_expr | prec2_expr "%=" prec14_expr | prec2_expr "<<=" prec14_expr | prec2_expr ">>=" prec14_expr | prec2_expr "&=" prec14_expr | prec2_expr "^=" prec14_expr | prec2_expr "|=" prec14_expr -> or_ass ?prec13_expr: prec12_expr | prec12_expr "?" prec13_expr ":" prec13_expr ?prec12_expr: prec11_expr | prec12_expr "||" prec11_expr ?prec11_expr: prec10_expr | prec11_expr "&&" prec10_expr ?prec10_expr: prec9_expr | prec10_expr "|" prec9_expr -> _or ?prec9_expr: prec8_expr | prec9_expr "^" prec8_expr ?prec8_expr: prec7_expr | prec8_expr "&" prec7_expr -> _and // reserved work in python ?prec7_expr: prec6_expr | prec7_expr "==" prec6_expr -> eq | prec7_expr "!=" prec6_expr -> neq ?prec6_expr: prec5_expr | prec6_expr "<" prec5_expr -> lt | prec6_expr "<=" prec5_expr -> lte | prec6_expr ">" prec5_expr -> gt | prec6_expr ">=" prec5_expr -> gte ?prec5_expr: prec4_expr | prec5_expr "<<" prec4_expr -> shl | prec5_expr ">>" prec4_expr -> shr ?prec4_expr: prec3_expr | prec4_expr "+" prec3_expr -> add | prec4_expr "-" prec3_expr -> sub ?prec3_expr: prec2_expr | prec3_expr "*" prec2_expr -> mul | prec3_expr "/" prec2_expr -> div | prec3_expr "%" prec2_expr -> mod ?prec2_expr: prec1_expr | "++" prec2_expr -> pre_increment | "--" prec2_expr -> pre_decrement | "+" prec2_expr | "-" prec2_expr | "!" prec2_expr -> bool_not | "~" prec2_expr | "(" (type | funptr_type) ")" prec2_expr -> cast | "*" prec2_expr -> dereference | "&" prec2_expr -> address_of | "sizeof" prec2_expr -> sizeof ?prec1_expr: literal | identifier | "(" expression ")" | prec1_expr "++" -> post_increment | prec1_expr "--" -> post_decrement | prec1_expr "(" expression? ")" -> fun_call | prec1_expr "[" expression "]" -> array_item | prec1_expr "." field -> field_access | prec1_expr "->" field -> pointer_access label: IDENTIFIER literal: SIGNED_NUMBER | ESCAPED_STRING | HEX_LITTERAL | CHARACTER field: IDENTIFIER identifier: IDENTIFIER ?symbol: IDENTIFIER type: type_qualifier* IDENTIFIER | struct_type | type "*" -> pointer ?array_size: INT funptr_type: type "(" "*" ")" "(" [fun_param ("," fun_param)*] ")" ?type_qualifier: "volatile" -> volatile | "const" -> const | "static" -> static | "extern" -> extern struct_type: "struct" (IDENTIFIER | IDENTIFIER? struct_body) struct_def: "struct" IDENTIFIER struct_body ";" struct_body: "{" struct_field* "}" struct_field: type IDENTIFIER sized_array* ";" IDENTIFIER: /[_a-zA-Z]\w*/ COMMENT: /\/\/.*/ HEX_LITTERAL: /0x[a-fA-F0-9]+/ CHARACTER: /'([^']|\\n|\\r|\\0|\\t)'/ %import common.WS %import common.CNAME %import common.C_COMMENT %import common.SIGNED_NUMBER %import common.INT %import common.ESCAPED_STRING %ignore COMMENT %ignore C_COMMENT %ignore WS