Add a preliminary version of const arrays. It sorta works. Right now this is limited to function-scope const arrays.
		
			
				
	
	
		
			162 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			EBNF
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			EBNF
		
	
	
	
	
	
| 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
 |