## 8 Declarations

decl_var | ::= | common_decl
| | | [storage] ctype COMMA_LIST(d_ident) ;
| | | [storage] [const_vol] id COMMA_LIST(d_ident) ;
| | | [storage] fn_ctype ( * d_ident ) ( PARAMSEQ(name_opt_decl, ε) ) = initialize ;
| | | typedef ctype typedef_ident ;
one_decl | ::= | common_decl
| | | [storage] ctype id;
| | | [storage] [const_vol] id d_ident ;
common_decl | ::= | ctype;
| | | funproto
| | | [storage] ctype d_ident = initialize ;
| | | [storage] [const_vol] id d_ident = initialize ;
| | | [storage] fn_ctype ( * d_ident ) ( PARAMSEQ(name_opt_decl, ε) ) ;
| | | decl_ident ( [COMMA_LIST(expr)] ) ;
initialize | ::= | dot_expr
| | | metaidInitialiser
| | | { [COMMA_LIST(init_list_elem)] }
init_list_elem | ::= | dot_expr
| | | designator = initialize
| | | metaidInitialiser
| | | metaidInitialiserList
| | | id : dot_expr
designator | ::= | . id
| | | [ dot_expr ]
| | | [ dot_expr ... dot_expr ]
decl_ident | ::= | DeclarerId
| | | metaidDeclarer

An initializer for a structure can be ordered or unordered. It is considered to be unordered if there is at least one key-value pair initializer, e.g., .x = e.

A declaration can have e.g. the form register x;. In this case, the variable implicitly has type int, and SmPL code that declares an int variable will match such a declaration. On the other hand, the implicit int type has no position. If the SmPL code tries to record the position of the type, the match will fail.