%{
#include <stdio.h>
#define YYERROR_VERBOSE
int yydebug = 1;
extern char yytext[];
extern int column;
int yylex(void);
void yyerror(char *s);
%}
%token IDENT HASH_IDENT CT_IDENT CONST_IDENT
%token TYPE_IDENT CT_TYPE_IDENT
%token AT_TYPE_IDENT AT_IDENT CT_INCLUDE
%token STRING_LITERAL INTEGER
%token INC_OP DEC_OP SHL_OP SHR_OP LE_OP GE_OP EQ_OP NE_OP
%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
%token SUB_ASSIGN SHL_ASSIGN SHR_ASSIGN AND_ASSIGN
%token XOR_ASSIGN OR_ASSIGN VAR NUL ELVIS NEXTCASE ANYFAULT
%token MODULE IMPORT DEF EXTERN
%token CHAR SHORT INT LONG FLOAT DOUBLE CONST VOID USZ ISZ UPTR IPTR ANY
%token ICHAR USHORT UINT ULONG BOOL INT128 UINT128 FLOAT16 FLOAT128 BFLOAT16
%token TYPEID BITSTRUCT STATIC BANGBANG AT_CONST_IDENT HASH_TYPE_IDENT
%token STRUCT UNION ENUM ELLIPSIS DOTDOT BYTES
%token CT_ERROR
%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR CONTINUE BREAK RETURN FOREACH_R FOREACH
%token FN FAULT MACRO CT_IF CT_ENDIF CT_ELSE CT_SWITCH CT_CASE CT_DEFAULT CT_FOR CT_FOREACH CT_ENDFOREACH
%token CT_ENDFOR CT_ENDSWITCH BUILTIN IMPLIES INITIALIZE FINALIZE CT_ECHO CT_ASSERT CT_EVALTYPE CT_VATYPE
%token TRY CATCH SCOPE DEFER LVEC RVEC OPTELSE CT_TYPEFROM CT_TYPEOF TLOCAL
%token CT_VASPLAT INLINE DISTINCT CT_VACONST CT_NAMEOF CT_VAREF CT_VACOUNT CT_VAARG
%token CT_SIZEOF CT_STRINGIFY CT_QNAMEOF CT_OFFSETOF CT_VAEXPR
%token CT_EXTNAMEOF CT_EVAL CT_DEFINED CT_CHECKS CT_ALIGNOF ASSERT
%token ASM CHAR_LITERAL REAL TRUE FALSE CT_CONST_IDENT
%token LBRAPIPE RBRAPIPE HASH_CONST_IDENT
%start translation_unit
%%
path
: IDENT SCOPE
| path IDENT SCOPE
;
path_const
: path CONST_IDENT
| CONST_IDENT
;
path_ident
: path IDENT
| IDENT
;
path_at_ident
: path AT_IDENT
| AT_IDENT
;
ident_expr
: CONST_IDENT
| IDENT
| AT_IDENT
;
local_ident_expr
: CT_IDENT
| HASH_IDENT
;
ct_call
: CT_ALIGNOF
| CT_DEFINED
| CT_EXTNAMEOF
| CT_NAMEOF
| CT_OFFSETOF
| CT_QNAMEOF
;
ct_analyse
: CT_EVAL
| CT_SIZEOF
| CT_STRINGIFY
;
ct_arg
: CT_VACONST
| CT_VAARG
| CT_VAREF
| CT_VAEXPR
;
flat_path
: primary_expr param_path
| type
| primary_expr
;
maybe_optional_type
: optional_type
| empty
;
string_expr
: STRING_LITERAL
| string_expr STRING_LITERAL
;
bytes_expr
: BYTES
| bytes_expr BYTES
;
expr_block
: LBRAPIPE opt_stmt_list RBRAPIPE
;
base_expr
: string_expr
| INTEGER
| bytes_expr
| NUL
| BUILTIN CONST_IDENT
| BUILTIN IDENT
| CHAR_LITERAL
| REAL
| TRUE
| FALSE
| path ident_expr
| ident_expr
| local_ident_expr
| type initializer_list
| type '.' access_ident
| type '.' CONST_IDENT
| '(' expr ')'
| expr_block
| ct_call '(' flat_path ')'
| ct_arg '(' expr ')'
| ct_analyse '(' expr ')'
| CT_VACOUNT
| CT_CHECKS '(' expression_list ')'
| lambda_decl compound_statement
;
primary_expr
: base_expr
| initializer_list
;
range_loc
: expr
| '^' expr
;
range_expr
: range_loc DOTDOT range_loc
| range_loc DOTDOT
| DOTDOT range_loc
| range_loc ':' range_loc
| ':' range_loc
| range_loc ':'
| DOTDOT
;
call_inline_attributes
: AT_IDENT
| call_inline_attributes AT_IDENT
;
call_invocation
: '(' call_arg_list ')'
| '(' call_arg_list ')' call_inline_attributes
;
access_ident
: IDENT
| AT_IDENT
| HASH_IDENT
| CT_EVAL '(' expr ')'
| TYPEID
;
call_trailing
: '[' range_loc ']'
| '[' range_expr ']'
| call_invocation
| call_invocation compound_statement
| '.' access_ident
| INC_OP
| DEC_OP
| '!'
| BANGBANG
;
call_stmt_expr
: base_expr
| call_stmt_expr call_trailing
;
call_expr
: primary_expr
| call_expr call_trailing
;
unary_expr
: call_expr
| unary_op unary_expr
;
unary_stmt_expr
: call_stmt_expr
| unary_op unary_expr
;
unary_op
: '&'
| AND_OP
| '*'
| '+'
| '-'
| '~'
| '!'
| INC_OP
| DEC_OP
| '(' type ')'
;
mult_op
: '*'
| '/'
| '%'
;
mult_expr
: unary_expr
| mult_expr mult_op unary_expr
;
mult_stmt_expr
: unary_stmt_expr
| mult_stmt_expr mult_op unary_expr
;
shift_op
: SHL_OP
| SHR_OP
;
shift_expr
: mult_expr
| shift_expr shift_op mult_expr
;
shift_stmt_expr
: mult_stmt_expr
| shift_stmt_expr shift_op mult_expr
;
bit_op
: '&'
| '^'
| '|'
;
bit_expr
: shift_expr
| bit_expr bit_op shift_expr
;
bit_stmt_expr
: shift_stmt_expr
| bit_stmt_expr bit_op shift_expr
;
additive_op
: '+'
| '-'
;
additive_expr
: bit_expr
| additive_expr additive_op bit_expr
;
additive_stmt_expr
: bit_stmt_expr
| additive_stmt_expr additive_op bit_expr
;
relational_op
: '<'
| '>'
| LE_OP
| GE_OP
| EQ_OP
| NE_OP
;
relational_expr
: additive_expr
| relational_expr relational_op additive_expr
;
relational_stmt_expr
: additive_stmt_expr
| relational_stmt_expr relational_op additive_expr
;
rel_or_lambda_expr
: relational_expr
| lambda_decl IMPLIES relational_expr
;
and_expr
: relational_expr
| and_expr AND_OP relational_expr
;
and_stmt_expr
: relational_stmt_expr
| and_stmt_expr AND_OP relational_expr
;
or_expr
: and_expr
| or_expr OR_OP and_expr
;
or_stmt_expr
: and_stmt_expr
| or_stmt_expr OR_OP and_expr
;
or_expr_with_suffix
: or_expr
| or_expr '?'
| or_expr '?' '!'
;
or_stmt_expr_with_suffix
: or_stmt_expr
| or_stmt_expr '?'
| or_stmt_expr '?' '!'
;
ternary_expr
: or_expr_with_suffix
| or_expr '?' expr ':' ternary_expr
| or_expr_with_suffix ELVIS ternary_expr
| or_expr_with_suffix OPTELSE ternary_expr
| lambda_decl implies_body
;
ternary_stmt_expr
: or_stmt_expr_with_suffix
| or_stmt_expr '?' expr ':' ternary_expr
| or_stmt_expr_with_suffix ELVIS ternary_expr
| or_stmt_expr_with_suffix OPTELSE ternary_expr
| lambda_decl implies_body
;
assignment_op
: '='
| ADD_ASSIGN
| SUB_ASSIGN
| MUL_ASSIGN
| DIV_ASSIGN
| MOD_ASSIGN
| SHL_ASSIGN
| SHR_ASSIGN
| AND_ASSIGN
| XOR_ASSIGN
| OR_ASSIGN
;
empty
:
;
assignment_expr
: ternary_expr
| CT_TYPE_IDENT '=' type
| unary_expr assignment_op assignment_expr
;
assignment_stmt_expr
: ternary_stmt_expr
| CT_TYPE_IDENT '=' type
| unary_stmt_expr assignment_op assignment_expr
;
implies_body
: IMPLIES expr
;
lambda_decl
: FN maybe_optional_type fn_parameter_list opt_attributes
;
expr_no_list
: assignment_stmt_expr
;
expr
: assignment_expr
;
constant_expr
: ternary_expr
;
param_path_element
: '[' expr ']'
| '[' expr DOTDOT expr ']'
| '.' IDENT
;
param_path
: param_path_element
| param_path param_path_element
;
arg : param_path '=' expr
| type
| param_path '=' type
| expr
| CT_VASPLAT '(' range_expr ')'
| CT_VASPLAT '(' ')'
| ELLIPSIS expr
;
arg_list
: arg
| arg_list ',' arg
;
call_arg_list
: arg_list
| arg_list ';'
| arg_list ';' parameters
| ';'
| ';' parameters
| empty
;
opt_arg_list_trailing
: arg_list
| arg_list ','
| empty
;
enum_constants
: enum_constant
| enum_constants ',' enum_constant
;
enum_list
: enum_constants
| enum_constants ','
;
enum_constant
: CONST_IDENT
| CONST_IDENT '(' arg_list ')'
| CONST_IDENT '(' arg_list ',' ')'
;
identifier_list
: IDENT
| identifier_list ',' IDENT
;
enum_param_decl
: type
| type IDENT
| type IDENT '=' expr
;
base_type
: VOID
| BOOL
| CHAR
| ICHAR
| SHORT
| USHORT
| INT
| UINT
| LONG
| ULONG
| INT128
| UINT128
| FLOAT
| DOUBLE
| FLOAT16
| BFLOAT16
| FLOAT128
| IPTR
| UPTR
| ISZ
| USZ
| ANYFAULT
| ANY
| TYPEID
| TYPE_IDENT
| path TYPE_IDENT
| CT_TYPE_IDENT
| CT_TYPEOF '(' expr ')'
| CT_TYPEFROM '(' constant_expr ')'
| CT_VATYPE '(' constant_expr ')'
| CT_EVALTYPE '(' constant_expr ')'
;
type
: base_type
| type '*'
| type '[' constant_expr ']'
| type '[' ']'
| type '[' '*' ']'
| type LVEC constant_expr RVEC
| type LVEC '*' RVEC
;
optional_type
: type
| type '!'
;
local_decl_after_type
: CT_IDENT
| CT_IDENT '=' constant_expr
| IDENT opt_attributes
| IDENT opt_attributes '=' expr
;
local_decl_storage
: STATIC
| TLOCAL
;
decl_or_expr
: var_decl
| optional_type local_decl_after_type
| expr
;
var_decl
: VAR IDENT '=' expr
| VAR CT_IDENT '=' expr
| VAR CT_IDENT
| VAR CT_TYPE_IDENT '=' type
| VAR CT_TYPE_IDENT
;
initializer_list
: '{' opt_arg_list_trailing '}'
;
ct_case_stmt
: CT_CASE constant_expr ':' opt_stmt_list
| CT_CASE type ':' opt_stmt_list
| CT_DEFAULT ':' opt_stmt_list
;
ct_switch_body
: ct_case_stmt
| ct_switch_body ct_case_stmt
;
ct_for_stmt
: CT_FOR '(' for_cond ')' opt_stmt_list CT_ENDFOR
;
ct_foreach_stmt
: CT_FOREACH '(' CT_IDENT ':' expr ')' opt_stmt_list CT_ENDFOREACH
| CT_FOREACH '(' CT_IDENT ',' CT_IDENT ':' expr ')' opt_stmt_list CT_ENDFOREACH
;
ct_switch
: CT_SWITCH '(' constant_expr ')'
| CT_SWITCH '(' type ')'
| CT_SWITCH
;
ct_switch_stmt
: ct_switch ct_switch_body CT_ENDSWITCH
;
var_stmt
: var_decl ';'
decl_stmt_after_type
: local_decl_after_type
| decl_stmt_after_type ',' local_decl_after_type
;
declaration_stmt
: const_declaration
| local_decl_storage optional_type decl_stmt_after_type ';'
| optional_type decl_stmt_after_type ';'
;
return_stmt
: RETURN expr ';'
| RETURN ';'
;
catch_unwrap_list
: relational_expr
| catch_unwrap_list ',' relational_expr
;
catch_unwrap
: CATCH catch_unwrap_list
| CATCH IDENT '=' catch_unwrap_list
| CATCH type IDENT '=' catch_unwrap_list
;
try_unwrap
: TRY rel_or_lambda_expr
| TRY IDENT '=' rel_or_lambda_expr
| TRY type IDENT '=' rel_or_lambda_expr
;
try_unwrap_chain
: try_unwrap
| try_unwrap_chain AND_OP try_unwrap
| try_unwrap_chain AND_OP rel_or_lambda_expr
;
default_stmt
: DEFAULT ':' opt_stmt_list
;
case_stmt
: CASE expr ':' opt_stmt_list
| CASE expr DOTDOT expr ':' opt_stmt_list
| CASE type ':' opt_stmt_list
;
switch_body
: case_stmt
| default_stmt
| switch_body case_stmt
| switch_body default_stmt
;
cond_repeat
: decl_or_expr
| cond_repeat ',' decl_or_expr
;
cond
: try_unwrap_chain
| catch_unwrap
| cond_repeat
| cond_repeat ',' try_unwrap_chain
| cond_repeat ',' catch_unwrap
;
else_part
: ELSE if_stmt
| ELSE compound_statement
;
if_stmt
: IF optional_label paren_cond '{' switch_body '}'
| IF optional_label paren_cond '{' switch_body '}' else_part
| IF optional_label paren_cond statement
| IF optional_label paren_cond compound_statement else_part
;
expr_list_eos
: expression_list ';'
| ';'
;
cond_eos
: cond ';'
| ';'
;
for_cond
: expr_list_eos cond_eos expression_list
| expr_list_eos cond_eos
;
for_stmt
: FOR optional_label '(' for_cond ')' statement
;
paren_cond
: '(' cond ')'
;
while_stmt
: WHILE optional_label paren_cond statement
;
do_stmt
: DO optional_label compound_statement WHILE '(' expr ')' ';'
| DO optional_label compound_statement ';'
;
optional_label_target
: CONST_IDENT
| empty
;
continue_stmt
: CONTINUE optional_label_target ';'
;
break_stmt
: BREAK optional_label_target ';'
;
nextcase_stmt
: NEXTCASE CONST_IDENT ':' expr ';'
| NEXTCASE expr ';'
| NEXTCASE CONST_IDENT ':' type ';'
| NEXTCASE type ';'
| NEXTCASE ';'
;
foreach_var
: optional_type '&' IDENT
| optional_type IDENT
| '&' IDENT
| IDENT
;
foreach_vars
: foreach_var
| foreach_var ',' foreach_var
;
foreach_stmt
: FOREACH optional_label '(' foreach_vars ':' expr ')' statement
: FOREACH_R optional_label '(' foreach_vars ':' expr ')' statement
;
defer_stmt
: DEFER statement
| DEFER TRY statement
| DEFER CATCH statement
;
ct_if_stmt
: CT_IF constant_expr ':' opt_stmt_list CT_ENDIF
| CT_IF constant_expr ':' opt_stmt_list CT_ELSE opt_stmt_list CT_ENDIF
;
assert_expr
: try_unwrap_chain
| expr
;
assert_stmt
: ASSERT '(' assert_expr ')' ';'
| ASSERT '(' assert_expr ',' expr ')' ';'
;
asm_stmts
: asm_stmt
| asm_stmts asm_stmt
;
asm_instr
: INT
| IDENT
| INT '.' IDENT
| IDENT '.' IDENT
;
asm_addr
: asm_expr
| asm_expr additive_op asm_expr
| asm_expr additive_op asm_expr '*' INTEGER
| asm_expr additive_op asm_expr '*' INTEGER additive_op INTEGER
| asm_expr additive_op asm_expr shift_op INTEGER
| asm_expr additive_op asm_expr additive_op INTEGER
;
asm_expr
: CT_IDENT
| CT_CONST_IDENT
| IDENT
| '&' IDENT
| CONST_IDENT
| REAL
| INTEGER
| '(' expr ')'
| '[' asm_addr ']'
asm_exprs
: asm_expr
| asm_exprs ',' asm_expr
;
asm_stmt
: asm_instr asm_exprs ';'
| asm_instr ';'
;
asm_block_stmt
: ASM '(' expr ')'
| ASM '{' asm_stmts '}'
| ASM '{' '}'
;
/* Order here matches compiler */
statement
: compound_statement
| var_stmt
| declaration_stmt
| return_stmt
| if_stmt
| while_stmt
| defer_stmt
| switch_stmt
| do_stmt
| for_stmt
| foreach_stmt
| continue_stmt
| break_stmt
| nextcase_stmt
| asm_block_stmt
| ct_echo_stmt
| ct_assert_stmt
| ct_if_stmt
| ct_switch_stmt
| ct_foreach_stmt
| ct_for_stmt
| expr_no_list ';'
| assert_stmt
| ';'
;
compound_statement
: '{' opt_stmt_list '}'
;
statement_list
: statement
| statement_list statement
;
opt_stmt_list
: statement_list
| empty
;
switch_stmt
: SWITCH optional_label '{' switch_body '}'
| SWITCH optional_label '{' '}'
| SWITCH optional_label paren_cond '{' switch_body '}'
| SWITCH optional_label paren_cond '{' '}'
;
expression_list
: decl_or_expr
| expression_list ',' decl_or_expr
;
optional_label
: CONST_IDENT ':'
| empty
;
ct_assert_stmt
: CT_ASSERT constant_expr ':' constant_expr ';'
| CT_ASSERT constant_expr ';'
| CT_ERROR constant_expr ';'
;
ct_include_stmt
: CT_INCLUDE string_expr ';'
;
ct_echo_stmt
: CT_ECHO constant_expr ';'
bitstruct_declaration
: BITSTRUCT TYPE_IDENT ':' type opt_attributes bitstruct_body
bitstruct_body
: '{' '}'
| '{' bitstruct_defs '}'
| '{' bitstruct_simple_defs '}'
;
bitstruct_defs
: bitstruct_def
| bitstruct_defs bitstruct_def
;
bitstruct_simple_defs
: base_type IDENT ';'
| bitstruct_simple_defs base_type IDENT ';'
;
bitstruct_def
: base_type IDENT ':' constant_expr DOTDOT constant_expr ';'
| base_type IDENT ':' constant_expr ';'
;
static_declaration
: STATIC INITIALIZE opt_attributes compound_statement
| STATIC FINALIZE opt_attributes compound_statement
;
attribute_name
: AT_IDENT
| AT_TYPE_IDENT
| path AT_TYPE_IDENT
;
attribute_operator_expr
: '&' '[' ']'
| '[' ']' '='
| '[' ']'
;
attr_param
: attribute_operator_expr
| constant_expr
;
attribute_param_list
: attr_param
| attribute_param_list ',' attr_param
;
attribute
: attribute_name
| attribute_name '(' attribute_param_list ')'
;
attribute_list
: attribute
| attribute_list attribute
;
opt_attributes
: attribute_list
| empty
;
trailing_block_param
: AT_IDENT
| AT_IDENT '(' ')'
| AT_IDENT '(' parameters ')'
;
macro_params
: parameters
| parameters ';' trailing_block_param
| ';' trailing_block_param
| empty
;
macro_func_body
: implies_body ';'
| compound_statement
;
macro_declaration
: MACRO macro_header '(' macro_params ')' opt_attributes macro_func_body
;
struct_or_union
: STRUCT
| UNION
;
struct_declaration
: struct_or_union TYPE_IDENT opt_attributes struct_body
;
struct_body
: '{' struct_declaration_list '}'
;
struct_declaration_list
: struct_member_decl
| struct_declaration_list struct_member_decl
;
enum_params
: enum_param_decl
| enum_params ',' enum_param_decl
;
enum_param_list
: '(' enum_params ')'
| '(' ')'
| empty
;
struct_member_decl
: type identifier_list opt_attributes ';'
| struct_or_union IDENT opt_attributes struct_body
| struct_or_union opt_attributes struct_body
| BITSTRUCT ':' type opt_attributes bitstruct_body
| BITSTRUCT IDENT ':' type opt_attributes bitstruct_body
| INLINE type IDENT opt_attributes ';'
| INLINE type opt_attributes ';'
;
enum_spec
: ':' type enum_param_list
| empty
;
enum_declaration
: ENUM TYPE_IDENT enum_spec opt_attributes '{' enum_list '}'
;
faults
: CONST_IDENT
| faults ',' CONST_IDENT
;
fault_declaration
: FAULT TYPE_IDENT opt_attributes '{' faults '}'
| FAULT TYPE_IDENT opt_attributes '{' faults ',' '}'
;
func_macro_name
: IDENT
| AT_IDENT
;
func_header
: optional_type type '.' func_macro_name
| optional_type func_macro_name
;
macro_header
: func_header
| type '.' func_macro_name
| func_macro_name
;
fn_parameter_list
: '(' parameters ')'
| '(' ')'
;
parameters
: parameter '=' expr
| parameter
| parameters ',' parameter
| parameters ',' parameter '=' expr
;
parameter
: type IDENT opt_attributes
| type ELLIPSIS IDENT opt_attributes
| type ELLIPSIS CT_IDENT
| type CT_IDENT
| type ELLIPSIS opt_attributes
| type HASH_IDENT opt_attributes
| type '&' IDENT opt_attributes
| type opt_attributes
| '&' IDENT opt_attributes
| HASH_IDENT opt_attributes
| ELLIPSIS
| IDENT opt_attributes
| IDENT ELLIPSIS opt_attributes
| CT_IDENT
| CT_IDENT ELLIPSIS
;
func_definition
: FN func_header fn_parameter_list opt_attributes ';'
| FN func_header fn_parameter_list opt_attributes macro_func_body
;
const_declaration
: CONST CONST_IDENT opt_attributes '=' expr ';'
| CONST type CONST_IDENT opt_attributes '=' expr ';'
;
func_typedef
: FN optional_type fn_parameter_list
;
opt_distinct_inline
: DISTINCT
| DISTINCT INLINE
| INLINE DISTINCT
| INLINE
| empty
;
generic_parameters
: bit_expr
| type
| generic_parameters ',' bit_expr
| generic_parameters ',' type
;
typedef_type
: func_typedef
| type opt_generic_parameters
;
multi_declaration
: ',' IDENT
| multi_declaration ',' IDENT
;
global_storage
: TLOCAL
| empty
;
global_declaration
: global_storage optional_type IDENT opt_attributes ';'
| global_storage optional_type IDENT multi_declaration opt_attributes ';'
| global_storage optional_type IDENT opt_attributes '=' expr ';'
;
opt_tl_stmts
: top_level_statements
| empty
;
tl_ct_case
: CT_CASE constant_expr ':' opt_tl_stmts
| CT_CASE type ':' opt_tl_stmts
| CT_DEFAULT ':' opt_tl_stmts
;
tl_ct_switch_body
: tl_ct_case
| tl_ct_switch_body tl_ct_case
;
define_attribute
: AT_TYPE_IDENT '(' parameters ')' opt_attributes '=' '{' opt_attributes '}'
| AT_TYPE_IDENT opt_attributes '=' '{' opt_attributes '}'
;
opt_generic_parameters
: '<' generic_parameters '>'
| empty
;
define_ident
: IDENT '=' path_ident opt_generic_parameters
| CONST_IDENT '=' path_const opt_generic_parameters
| AT_IDENT '=' path_at_ident opt_generic_parameters
;
define_declaration
: DEF define_ident ';'
| DEF define_attribute ';'
| DEF TYPE_IDENT opt_attributes '=' opt_distinct_inline typedef_type ';'
;
tl_ct_if
: CT_IF constant_expr ':' opt_tl_stmts CT_ENDIF
| CT_IF constant_expr ':' opt_tl_stmts CT_ELSE opt_tl_stmts CT_ENDIF
;
tl_ct_switch
: ct_switch tl_ct_switch_body CT_ENDSWITCH
;
module_param
: CONST_IDENT
| TYPE_IDENT
;
module_params
: module_param
| module_params ',' module_param
;
module
: MODULE path_ident opt_attributes ';'
| MODULE path_ident '<' module_params '>' opt_attributes ';'
;
import_paths
: path_ident
| path_ident ',' path_ident
;
import_decl
: IMPORT import_paths opt_attributes ';'
;
translation_unit
: top_level_statements
| empty
;
top_level_statements
: top_level
| top_level_statements top_level
;
opt_extern
: EXTERN
| empty
;
top_level
: module
| import_decl
| opt_extern func_definition
| opt_extern const_declaration
| opt_extern global_declaration
| ct_assert_stmt
| ct_echo_stmt
| ct_include_stmt
| tl_ct_if
| tl_ct_switch
| struct_declaration
| fault_declaration
| enum_declaration
| macro_declaration
| define_declaration
| static_declaration
| bitstruct_declaration
;
%%
void yyerror(char *s)
{
fflush(stdout);
printf("\n%*s\n%*s\n", column, "^", column, s);
}
int main(int argc, char *argv[])
{
yyparse();
return 0;
}