| t | <<< ========================================================= | t | <<< ========================================================= |
| Vitte — Complete Core Grammar | | Vitte — Complete Core Grammar |
| systems + application + kernel + compiler surface | | systems + application + kernel + compiler surface |
| canonical blocks: { } | | canonical blocks: { } |
| canonical syntax source for parser/docs/tests | | canonical syntax source for parser/docs/tests |
| low-level capable | | low-level capable |
| compiler-capable | | compiler-capable |
| no aliases, reduced duplicates | | no aliases, reduced duplicates |
| ========================================================= >>> | | ========================================================= >>> |
| | | |
| program ::= WS? { toplevel WS? } EOF ; | | program ::= WS? { toplevel WS? } EOF ; |
| | | |
| <<< ================= Top-level ================= >>> | | <<< ================= Top-level ================= >>> |
| | | |
| toplevel ::= inner_attribute | | toplevel ::= inner_attribute |
| | space_decl | | | space_decl |
| | use_decl | | | use_decl |
| | export_decl | | | export_decl |
| | const_decl | | | const_decl |
| | static_decl | | | static_decl |
| | global_decl | | | global_decl |
| | type_alias_decl | | | type_alias_decl |
| | opaque_type_decl | | | opaque_type_decl |
| | extern_type_decl | | | extern_type_decl |
| | form_decl | | | form_decl |
| | class_decl | | | class_decl |
| | union_decl | | | union_decl |
| | bits_decl | | | bits_decl |
| | pick_decl | | | pick_decl |
| | flags_decl | | | flags_decl |
| | trait_decl | | | trait_decl |
| | impl_decl | | | impl_decl |
| | extern_block | | | extern_block |
| | proc_decl | | | proc_decl |
| | intrinsic_decl | | | intrinsic_decl |
| | compiler_decl | | | compiler_decl |
| | query_decl | | | query_decl |
| | pass_decl | | | pass_decl |
| | backend_decl | | | backend_decl |
| | diagnostic_decl | | | diagnostic_decl |
| | macro_decl | | | macro_decl |
| | comptime_decl | | | comptime_decl |
| | static_assert_decl | | | static_assert_decl |
| | test_decl | | | test_decl |
| | bench_decl | | | bench_decl |
| | entry_decl | | | entry_decl |
| ; | | ; |
| | | |
| space_decl ::= "space" WS1 module_path ; | | space_decl ::= "space" WS1 module_path ; |
| | | |
| use_decl ::= "use" WS1 package_path [ use_group | use_glob ] [ WS1 "as" WS1 ident ] ; | | use_decl ::= "use" WS1 package_path [ use_group | use_glob ] [ WS1 "as" WS1 ident ] ; |
| use_glob ::= "." "*" ; | | use_glob ::= "." "*" ; |
| use_group ::= "." "{" WS? ( "*" | import_items [ WS? "," WS? "*" ]? ) WS? "}" ; | | use_group ::= "." "{" WS? ( "*" | import_items [ WS? "," WS? "*" ]? ) WS? "}" ; |
| | | |
| import_items ::= import_item { WS? "," WS? import_item } [ WS? "," ] ; | | import_items ::= import_item { WS? "," WS? import_item } [ WS? "," ] ; |
| import_item ::= ident [ WS1 "as" WS1 ident ] ; | | import_item ::= ident [ WS1 "as" WS1 ident ] ; |
| | | |
| export_decl ::= "export" WS1 ( "*" | ident_list | "{" WS? ident_list WS? "}" ) ; | | export_decl ::= "export" WS1 ( "*" | ident_list | "{" WS? ident_list WS? "}" ) ; |
| | | |
| const_decl ::= { attr_prefix WS? } "const" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ; | | const_decl ::= { attr_prefix WS? } "const" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ; |
| static_decl ::= { attr_prefix WS? } "static" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ; | | static_decl ::= { attr_prefix WS? } "static" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ; |
| global_decl ::= { attr_prefix WS? } "global" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ; | | global_decl ::= { attr_prefix WS? } "global" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ; |
| | | |
| type_alias_decl ::= { attr_prefix WS? } "type" WS1 ident [ generic_params ] WS? "=" WS? type_expr ; | | type_alias_decl ::= { attr_prefix WS? } "type" WS1 ident [ generic_params ] WS? "=" WS? type_expr ; |
| opaque_type_decl ::= { attr_prefix WS? } "opaque" WS1 "type" WS1 ident [ generic_params ] [ WS? "=" WS? type_expr ] ; | | opaque_type_decl ::= { attr_prefix WS? } "opaque" WS1 "type" WS1 ident [ generic_params ] [ WS? "=" WS? type_expr ] ; |
| extern_type_decl ::= { attr_prefix WS? } "extern" WS1 "type" WS1 ident [ generic_params ] [ WS? ";" ] ; | | extern_type_decl ::= { attr_prefix WS? } "extern" WS1 "type" WS1 ident [ generic_params ] [ WS? ";" ] ; |
| | | |
| form_decl ::= { attr_prefix WS? } "form" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? form_items? WS? " | | form_decl ::= { attr_prefix WS? } "form" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? form_items? WS? " |
| }" ; | | }" ; |
| class_decl ::= { attr_prefix WS? } "class" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? class_items? WS | | class_decl ::= { attr_prefix WS? } "class" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? class_items? WS |
| ? "}" ; | | ? "}" ; |
| union_decl ::= { attr_prefix WS? } "union" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? field_list? WS? | | union_decl ::= { attr_prefix WS? } "union" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? field_list? WS? |
| "}" ; | | "}" ; |
| | | |
| form_items ::= form_item { WS? ","? WS? form_item } [ WS? "," ] ; | | form_items ::= form_item { WS? ","? WS? form_item } [ WS? "," ] ; |
| form_item ::= field_item | const_decl | type_alias_decl | proc_decl ; | | form_item ::= field_item | const_decl | type_alias_decl | proc_decl ; |
| | | |
| class_items ::= class_item { WS? ","? WS? class_item } [ WS? "," ] ; | | class_items ::= class_item { WS? ","? WS? class_item } [ WS? "," ] ; |
| class_item ::= field_item | const_decl | type_alias_decl | proc_decl ; | | class_item ::= field_item | const_decl | type_alias_decl | proc_decl ; |
| | | |
| field_list ::= field_item { WS? "," WS? field_item } [ WS? "," ] ; | | field_list ::= field_item { WS? "," WS? field_item } [ WS? "," ] ; |
| field_item ::= { attr_prefix WS? } [ visibility WS1 ] ident WS? ":" WS? type_expr [ WS? "=" WS? expr ] ; | | field_item ::= { attr_prefix WS? } [ visibility WS1 ] ident WS? ":" WS? type_expr [ WS? "=" WS? expr ] ; |
| | | |
| bits_decl ::= { attr_prefix WS? } "bits" WS1 ident [ WS? ":" WS? type_expr ] WS? "{" WS? bitfield_list? WS? "}" ; | | bits_decl ::= { attr_prefix WS? } "bits" WS1 ident [ WS? ":" WS? type_expr ] WS? "{" WS? bitfield_list? WS? "}" ; |
| bitfield_list ::= bitfield_item { WS? "," WS? bitfield_item } [ WS? "," ] ; | | bitfield_list ::= bitfield_item { WS? "," WS? bitfield_item } [ WS? "," ] ; |
| bitfield_item ::= ident WS? ":" WS? expr WS? ".." WS? expr ; | | bitfield_item ::= ident WS? ":" WS? expr WS? ".." WS? expr ; |
| | | |
| pick_decl ::= { attr_prefix WS? } "pick" WS1 ident [ generic_params ] [ WS? ":" WS? type_expr ] [ WS? where_clause ] WS? | | pick_decl ::= { attr_prefix WS? } "pick" WS1 ident [ generic_params ] [ WS? ":" WS? type_expr ] [ WS? where_clause ] WS? |
| "{" WS? case_list? WS? "}" ; | | "{" WS? case_list? WS? "}" ; |
| case_list ::= case_item { WS? "," WS? case_item } [ WS? "," ] ; | | case_list ::= case_item { WS? "," WS? case_item } [ WS? "," ] ; |
| case_item ::= [ "case" WS1 ] ident [ "(" WS? case_payload? WS? ")" ] [ WS? "=" WS? expr ] ; | | case_item ::= [ "case" WS1 ] ident [ "(" WS? case_payload? WS? ")" ] [ WS? "=" WS? expr ] ; |
| case_payload ::= case_field { WS? "," WS? case_field } [ WS? "," ] ; | | case_payload ::= case_field { WS? "," WS? case_field } [ WS? "," ] ; |
| case_field ::= ident WS? ":" WS? type_expr | type_expr ; | | case_field ::= ident WS? ":" WS? type_expr | type_expr ; |
| | | |
| flags_decl ::= { attr_prefix WS? } "flags" WS1 ident [ WS? ":" WS? type_expr ] WS? "{" WS? flag_list? WS? "}" ; | | flags_decl ::= { attr_prefix WS? } "flags" WS1 ident [ WS? ":" WS? type_expr ] WS? "{" WS? flag_list? WS? "}" ; |
| flag_list ::= flag_item { WS? "," WS? flag_item } [ WS? "," ] ; | | flag_list ::= flag_item { WS? "," WS? flag_item } [ WS? "," ] ; |
| flag_item ::= ident [ WS? "=" WS? expr ] ; | | flag_item ::= ident [ WS? "=" WS? expr ] ; |
| | | |
| trait_decl ::= { attr_prefix WS? } [ "unsafe" WS1 ] "trait" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS | | trait_decl ::= { attr_prefix WS? } [ "unsafe" WS1 ] "trait" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS |
| ? trait_item* WS? "}" ; | | ? trait_item* WS? "}" ; |
| trait_item ::= proc_signature | const_decl | associated_type_decl ; | | trait_item ::= proc_signature | const_decl | associated_type_decl ; |
| | | |
| associated_type_decl ::= "type" WS1 ident [ WS? ":" WS? trait_bound ] [ WS? "=" WS? type_expr ] ; | | associated_type_decl ::= "type" WS1 ident [ WS? ":" WS? trait_bound ] [ WS? "=" WS? type_expr ] ; |
| | | |
| impl_decl ::= { attr_prefix WS? } [ "unsafe" WS1 ] "impl" WS1 impl_head [ WS? where_clause ] WS? "{" WS? impl_item* WS? | | impl_decl ::= { attr_prefix WS? } [ "unsafe" WS1 ] "impl" WS1 impl_head [ WS? where_clause ] WS? "{" WS? impl_item* WS? |
| "}" ; | | "}" ; |
| impl_head ::= type_expr | type_expr WS1 "for" WS1 type_expr ; | | impl_head ::= type_expr | type_expr WS1 "for" WS1 type_expr ; |
| impl_item ::= const_decl | type_alias_decl | associated_type_decl | proc_decl ; | | impl_item ::= const_decl | type_alias_decl | associated_type_decl | proc_decl ; |
| | | |
| proc_signature ::= { attr_prefix WS? } "proc" WS1 ident [ generic_params ] | | proc_signature ::= { attr_prefix WS? } "proc" WS1 ident [ generic_params ] |
| "(" WS? param_list? WS? ")" | | "(" WS? param_list? WS? ")" |
| [ WS? "->" WS? type_expr ] | | [ WS? "->" WS? type_expr ] |
| WS? proc_suffix* | | WS? proc_suffix* |
| WS? ";" | | WS? ";" |
| ; | | ; |
| | | |
| proc_decl ::= { attr_prefix WS? } [ visibility WS1 ] proc_modifier* [ extern_clause WS1 ] "proc" WS1 proc_name [ generic | | proc_decl ::= { attr_prefix WS? } [ visibility WS1 ] proc_modifier* [ extern_clause WS1 ] "proc" WS1 proc_name [ generic |
| _params ] | | _params ] |
| "(" WS? param_list? WS? ")" | | "(" WS? param_list? WS? ")" |
| [ WS? "->" WS? type_expr ] | | [ WS? "->" WS? type_expr ] |
| WS? proc_suffix* | | WS? proc_suffix* |
| WS? ( block | ";" ) | | WS? ( block | ";" ) |
| ; | | ; |
| | | |
| proc_name ::= ident | "operator" WS? operator_symbol ; | | proc_name ::= ident | "operator" WS? operator_symbol ; |
| operator_symbol ::= "+" | "-" | "*" | "/" | "%" | | operator_symbol ::= "+" | "-" | "*" | "/" | "%" |
| | "==" | "!=" | "<" | "<=" | ">" | ">=" | | | "==" | "!=" | "<" | "<=" | ">" | ">=" |
| | "[]" | "()" ; | | | "[]" | "()" ; |
| | | |
| proc_modifier ::= "async" WS1 | | proc_modifier ::= "async" WS1 |
| | "unsafe" WS1 | | | "unsafe" WS1 |
| | "const" WS1 | | | "const" WS1 |
| | "inline" WS1 | | | "inline" WS1 |
| | "noinline" WS1 | | | "noinline" WS1 |
| | "naked" WS1 | | | "naked" WS1 |
| | "interrupt" WS1 | | | "interrupt" WS1 |
| ; | | ; |
| | | |
| proc_suffix ::= effects_clause | | proc_suffix ::= effects_clause |
| | requires_clause | | | requires_clause |
| | where_clause | | | where_clause |
| | "noexcept" | | | "noexcept" |
| ; | | ; |
| | | |
| extern_block ::= { attr_prefix WS? } "extern" WS1 extern_abi WS? "{" WS? extern_item* WS? "}" ; | | extern_block ::= { attr_prefix WS? } "extern" WS1 extern_abi WS? "{" WS? extern_item* WS? "}" ; |
| extern_item ::= extern_proc_decl | extern_type_decl | const_decl ; | | extern_item ::= extern_proc_decl | extern_type_decl | const_decl ; |
| | | |
| extern_proc_decl ::= { attr_prefix WS? } "proc" WS1 ident [ generic_params ] | | extern_proc_decl ::= { attr_prefix WS? } "proc" WS1 ident [ generic_params ] |
| "(" WS? param_list? WS? ")" | | "(" WS? param_list? WS? ")" |
| [ WS? "->" WS? type_expr ] | | [ WS? "->" WS? type_expr ] |
| WS? proc_suffix* | | WS? proc_suffix* |
| WS? ";" | | WS? ";" |
| ; | | ; |
| | | |
| extern_clause ::= "extern" WS1 extern_abi ; | | extern_clause ::= "extern" WS1 extern_abi ; |
| extern_abi ::= callconv | string_lit ; | | extern_abi ::= callconv | string_lit ; |
| callconv ::= "C" | "sysv64" | "win64" | "interrupt" | "naked" ; | | callconv ::= "C" | "sysv64" | "win64" | "interrupt" | "naked" ; |
| | | |
| intrinsic_decl ::= { attr_prefix WS? } "intrinsic" WS1 ident [ generic_params ] | | intrinsic_decl ::= { attr_prefix WS? } "intrinsic" WS1 ident [ generic_params ] |
| "(" WS? param_list? WS? ")" | | "(" WS? param_list? WS? ")" |
| [ WS? "->" WS? type_expr ] | | [ WS? "->" WS? type_expr ] |
| WS? ";" | | WS? ";" |
| ; | | ; |
| | | |
| macro_decl ::= { attr_prefix WS? } "macro" WS1 ident "(" WS? macro_param_list? WS? ")" WS? block ; | | macro_decl ::= { attr_prefix WS? } "macro" WS1 ident "(" WS? macro_param_list? WS? ")" WS? block ; |
| macro_param_list ::= macro_param { WS? "," WS? macro_param } [ WS? "," ] ; | | macro_param_list ::= macro_param { WS? "," WS? macro_param } [ WS? "," ] ; |
| macro_param ::= ident [ WS? ":" WS? macro_kind ] ; | | macro_param ::= ident [ WS? ":" WS? macro_kind ] ; |
| macro_kind ::= "expr" | "stmt" | "type" | "ident" | "block" | "item" ; | | macro_kind ::= "expr" | "stmt" | "type" | "ident" | "block" | "item" ; |
| | | |
| comptime_decl ::= "comptime" WS? block ; | | comptime_decl ::= "comptime" WS? block ; |
| static_assert_decl ::= "static_assert" WS? "(" WS? expr [ WS? "," WS? expr ] WS? ")" ; | | static_assert_decl ::= "static_assert" WS? "(" WS? expr [ WS? "," WS? expr ] WS? ")" ; |
| test_decl ::= { attr_prefix WS? } "test" WS1 string_lit WS? block ; | | test_decl ::= { attr_prefix WS? } "test" WS1 string_lit WS? block ; |
| bench_decl ::= { attr_prefix WS? } "bench" WS1 string_lit WS? block ; | | bench_decl ::= { attr_prefix WS? } "bench" WS1 string_lit WS? block ; |
| entry_decl ::= { attr_prefix WS? } "entry" WS1 ident WS1 "at" WS1 module_path WS? block ; | | entry_decl ::= { attr_prefix WS? } "entry" WS1 ident WS1 "at" WS1 module_path WS? block ; |
| | | |
| visibility ::= "pub" | "priv" | "pub" WS? "(" WS? visibility_scope WS? ")" ; | | visibility ::= "pub" | "priv" | "pub" WS? "(" WS? visibility_scope WS? ")" ; |
| visibility_scope ::= "package" | "module" | "super" ; | | visibility_scope ::= "package" | "module" | "super" ; |
| | | |
| generic_params ::= "[" WS? generic_param_list? WS? "]" ; | | generic_params ::= "[" WS? generic_param_list? WS? "]" ; |
| generic_param_list ::= generic_param { WS? "," WS? generic_param } [ WS? "," ] ; | | generic_param_list ::= generic_param { WS? "," WS? generic_param } [ WS? "," ] ; |
| generic_param ::= ident [ WS? ":" WS? trait_bound ] [ WS? "=" WS? type_expr ] | | generic_param ::= ident [ WS? ":" WS? trait_bound ] [ WS? "=" WS? type_expr ] |
| | "const" WS1 ident WS? ":" WS? type_expr | | | "const" WS1 ident WS? ":" WS? type_expr |
| | "comptime" WS1 ident WS? ":" WS? type_expr | | | "comptime" WS1 ident WS? ":" WS? type_expr |
| ; | | ; |
| | | |
| where_clause ::= "where" WS1 where_bounds ; | | where_clause ::= "where" WS1 where_bounds ; |
| where_bounds ::= where_bound { WS? "," WS? where_bound } [ WS? "," ] ; | | where_bounds ::= where_bound { WS? "," WS? where_bound } [ WS? "," ] ; |
| where_bound ::= type_expr WS? ":" WS? trait_bound | | where_bound ::= type_expr WS? ":" WS? trait_bound |
| | type_expr WS? "==" WS? type_expr | | | type_expr WS? "==" WS? type_expr |
| | expr WS? rel_op WS? expr | | | expr WS? rel_op WS? expr |
| ; | | ; |
| | | |
| trait_bound ::= type_expr { WS? "+" WS? type_expr } ; | | trait_bound ::= type_expr { WS? "+" WS? type_expr } ; |
| | | |
| param_list ::= param { WS? "," WS? param } [ WS? "," ] ; | | param_list ::= param { WS? "," WS? param } [ WS? "," ] ; |
| param ::= self_param | normal_param | variadic_param ; | | param ::= self_param | normal_param | variadic_param ; |
| self_param ::= [ "&" WS? ] [ "mut" WS1 ] "self" ; | | self_param ::= [ "&" WS? ] [ "mut" WS1 ] "self" ; |
| normal_param ::= [ param_mode WS1 ] pattern [ WS? ":" WS? type_expr ] [ WS? "=" WS? expr ] ; | | normal_param ::= [ param_mode WS1 ] pattern [ WS? ":" WS? type_expr ] [ WS? "=" WS? expr ] ; |
| variadic_param ::= "..." | ident WS? ":" WS? "..." type_expr ; | | variadic_param ::= "..." | ident WS? ":" WS? "..." type_expr ; |
| param_mode ::= "mut" | "owned" | "borrow" | "move" ; | | param_mode ::= "mut" | "owned" | "borrow" | "move" ; |
| | | |
| effects_clause ::= "effects" WS? "(" WS? ident_list? WS? ")" ; | | effects_clause ::= "effects" WS? "(" WS? ident_list? WS? ")" ; |
| requires_clause ::= "requires" WS? "(" WS? capability_list? WS? ")" ; | | requires_clause ::= "requires" WS? "(" WS? capability_list? WS? ")" ; |
| capability_list ::= capability { WS? "," WS? capability } [ WS? "," ] ; | | capability_list ::= capability { WS? "," WS? capability } [ WS? "," ] ; |
| capability ::= ident { "." ident } ; | | capability ::= ident { "." ident } ; |
| | | |
| module_path ::= relative? package_parts ; | | module_path ::= relative? package_parts ; |
| package_path ::= relative? package_parts ; | | package_path ::= relative? package_parts ; |
| relative ::= { "." } ; | | relative ::= { "." } ; |
| package_parts ::= ident { ( "/" | "." | "::" ) ident } ; | | package_parts ::= ident { ( "/" | "." | "::" ) ident } ; |
| ident_list ::= ident { WS? "," WS? ident } [ WS? "," ] ; | | ident_list ::= ident { WS? "," WS? ident } [ WS? "," ] ; |
| | | |
| <<< ================= Compiler Declarations ================= >>> | | <<< ================= Compiler Declarations ================= >>> |
| | | |
| compiler_decl ::= { attr_prefix WS? } "compiler" WS1 ident WS? "{" WS? compiler_items? WS? "}" ; | | compiler_decl ::= { attr_prefix WS? } "compiler" WS1 ident WS? "{" WS? compiler_items? WS? "}" ; |
| compiler_items ::= compiler_item { WS? compiler_item } ; | | compiler_items ::= compiler_item { WS? compiler_item } ; |
| | | |
| compiler_item ::= compiler_phase_decl | | compiler_item ::= compiler_phase_decl |
| | compiler_stage_decl | | | compiler_stage_decl |
| | compiler_artifact_decl | | | compiler_artifact_decl |
| | compiler_pipeline_decl | | | compiler_pipeline_decl |
| | compiler_cache_decl | | | compiler_cache_decl |
| | compiler_target_decl | | | compiler_target_decl |
| ; | | ; |
| | | |
| compiler_phase_decl ::= "phase" WS1 ident WS? "{" WS? | | compiler_phase_decl ::= "phase" WS1 ident WS? "{" WS? |
| "input" WS? ":" WS? type_expr WS? ";" | | "input" WS? ":" WS? type_expr WS? ";" |
| "output" WS? ":" WS? type_expr WS? ";" | | "output" WS? ":" WS? type_expr WS? ";" |
| [ "errors" WS? ":" WS? type_expr WS? ";" ] | | [ "errors" WS? ":" WS? type_expr WS? ";" ] |
| WS? "}" ; | | WS? "}" ; |
| | | |
| compiler_stage_decl ::= "stage" WS1 ident WS? ":" WS? ident_list WS? ";" ; | | compiler_stage_decl ::= "stage" WS1 ident WS? ":" WS? ident_list WS? ";" ; |
| compiler_artifact_decl ::= "artifact" WS1 ident WS? ":" WS? type_expr WS? ";" ; | | compiler_artifact_decl ::= "artifact" WS1 ident WS? ":" WS? type_expr WS? ";" ; |
| | | |
| compiler_pipeline_decl ::= "pipeline" WS1 ident WS? "{" WS? pipeline_step* WS? "}" ; | | compiler_pipeline_decl ::= "pipeline" WS1 ident WS? "{" WS? pipeline_step* WS? "}" ; |
| pipeline_step ::= "run" WS1 ident [ WS? "as" WS? ident ] WS? ";" | | pipeline_step ::= "run" WS1 ident [ WS? "as" WS? ident ] WS? ";" |
| | "dump" WS1 ident WS? ";" | | | "dump" WS1 ident WS? ";" |
| | "verify" WS1 ident WS? ";" | | | "verify" WS1 ident WS? ";" |
| ; | | ; |
| | | |
| compiler_cache_decl ::= "cache" WS1 ident WS? "{" WS? cache_item* WS? "}" ; | | compiler_cache_decl ::= "cache" WS1 ident WS? "{" WS? cache_item* WS? "}" ; |
| cache_item ::= "key" WS? ":" WS? type_expr WS? ";" | | cache_item ::= "key" WS? ":" WS? type_expr WS? ";" |
| | "value" WS? ":" WS? type_expr WS? ";" | | | "value" WS? ":" WS? type_expr WS? ";" |
| | "strategy" WS? ":" WS? ident WS? ";" | | | "strategy" WS? ":" WS? ident WS? ";" |
| ; | | ; |
| | | |
| compiler_target_decl ::= "target" WS1 ident WS? "{" WS? target_item* WS? "}" ; | | compiler_target_decl ::= "target" WS1 ident WS? "{" WS? target_item* WS? "}" ; |
| target_item ::= ident WS? ":" WS? expr WS? ";" ; | | target_item ::= ident WS? ":" WS? expr WS? ";" ; |
| | | |
| query_decl ::= { attr_prefix WS? } "query" WS1 ident | | query_decl ::= { attr_prefix WS? } "query" WS1 ident |
| "(" WS? param_list? WS? ")" | | "(" WS? param_list? WS? ")" |
| WS? "->" WS? type_expr | | WS? "->" WS? type_expr |
| WS? query_body ; | | WS? query_body ; |
| | | |
| query_body ::= block | ";" ; | | query_body ::= block | ";" ; |
| | | |
| pass_decl ::= { attr_prefix WS? } "pass" WS1 ident WS? "{" WS? pass_items? WS? "}" ; | | pass_decl ::= { attr_prefix WS? } "pass" WS1 ident WS? "{" WS? pass_items? WS? "}" ; |
| pass_items ::= pass_item { WS? pass_item } ; | | pass_items ::= pass_item { WS? pass_item } ; |
| pass_item ::= "input" WS? ":" WS? type_expr WS? ";" | | pass_item ::= "input" WS? ":" WS? type_expr WS? ";" |
| | "output" WS? ":" WS? type_expr WS? ";" | | | "output" WS? ":" WS? type_expr WS? ";" |
| | "requires" WS? ":" WS? ident_list WS? ";" | | | "requires" WS? ":" WS? ident_list WS? ";" |
| | "invalidates" WS? ":" WS? ident_list WS? ";" | | | "invalidates" WS? ":" WS? ident_list WS? ";" |
| | proc_decl | | | proc_decl |
| ; | | ; |
| | | |
| backend_decl ::= { attr_prefix WS? } "backend" WS1 ident WS? "{" WS? backend_items? WS? "}" ; | | backend_decl ::= { attr_prefix WS? } "backend" WS1 ident WS? "{" WS? backend_items? WS? "}" ; |
| backend_items ::= backend_item { WS? backend_item } ; | | backend_items ::= backend_item { WS? backend_item } ; |
| backend_item ::= "target" WS? ":" WS? string_lit WS? ";" | | backend_item ::= "target" WS? ":" WS? string_lit WS? ";" |
| | "format" WS? ":" WS? backend_format WS? ";" | | | "format" WS? ":" WS? backend_format WS? ";" |
| | "emits" WS? ":" WS? backend_output WS? ";" | | | "emits" WS? ":" WS? backend_output WS? ";" |
| | "requires" WS? ":" WS? ident_list WS? ";" | | | "requires" WS? ":" WS? ident_list WS? ";" |
| | proc_decl | | | proc_decl |
| ; | | ; |
| | | |
| backend_format ::= "c" | "llvm" | "asm" | "object" | "wasm" | "ir" ; | | backend_format ::= "c" | "llvm" | "asm" | "object" | "wasm" | "ir" ; |
| backend_output ::= "source" | "assembly" | "object" | "executable" | "library" ; | | backend_output ::= "source" | "assembly" | "object" | "executable" | "library" ; |
| | | |
| diagnostic_decl ::= { attr_prefix WS? } "diagnostic" WS1 diagnostic_code WS? "{" WS? diagnostic_items? WS? "}" ; | | diagnostic_decl ::= { attr_prefix WS? } "diagnostic" WS1 diagnostic_code WS? "{" WS? diagnostic_items? WS? "}" ; |
| diagnostic_code ::= ident | string_lit ; | | diagnostic_code ::= ident | string_lit ; |
| diagnostic_items ::= diagnostic_item { WS? diagnostic_item } ; | | diagnostic_items ::= diagnostic_item { WS? diagnostic_item } ; |
| | | |
| diagnostic_item ::= "level" WS? ":" WS? diagnostic_level WS? ";" | | diagnostic_item ::= "level" WS? ":" WS? diagnostic_level WS? ";" |
| | "message" WS? ":" WS? string_lit WS? ";" | | | "message" WS? ":" WS? string_lit WS? ";" |
| | "label" WS? ":" WS? string_lit WS? ";" | | | "label" WS? ":" WS? string_lit WS? ";" |
| | "help" WS? ":" WS? string_lit WS? ";" | | | "help" WS? ":" WS? string_lit WS? ";" |
| | "note" WS? ":" WS? string_lit WS? ";" | | | "note" WS? ":" WS? string_lit WS? ";" |
| | "suggest" WS? ":" WS? string_lit WS? ";" | | | "suggest" WS? ":" WS? string_lit WS? ";" |
| ; | | ; |
| | | |
| diagnostic_level ::= "error" | "warning" | "note" | "help" | "fatal" ; | | diagnostic_level ::= "error" | "warning" | "note" | "help" | "fatal" ; |
| | | |
| <<< ================= Attributes ================= >>> | | <<< ================= Attributes ================= >>> |
| | | |
| attr_prefix ::= outer_attribute | doc_comment | docstring ; | | attr_prefix ::= outer_attribute | doc_comment | docstring ; |
| inner_attribute ::= "#![" attr_path [ "(" WS? attr_arg_list? WS? ")" ] "]" ; | | inner_attribute ::= "#![" attr_path [ "(" WS? attr_arg_list? WS? ")" ] "]" ; |
| outer_attribute ::= "#[" attr_path [ "(" WS? attr_arg_list? WS? ")" ] "]" ; | | outer_attribute ::= "#[" attr_path [ "(" WS? attr_arg_list? WS? ")" ] "]" ; |
| doc_comment ::= "///" { ~NEWLINE ANY } ; | | doc_comment ::= "///" { ~NEWLINE ANY } ; |
| docstring ::= raw_string_lit ; | | docstring ::= raw_string_lit ; |
| | | |
| attr_path ::= ident { "." ident } ; | | attr_path ::= ident { "." ident } ; |
| attr_arg_list ::= attr_arg { WS? "," WS? attr_arg } [ WS? "," ] ; | | attr_arg_list ::= attr_arg { WS? "," WS? attr_arg } [ WS? "," ] ; |
| attr_arg ::= ident | | attr_arg ::= ident |
| | string_lit | | | string_lit |
| | int_lit | | | int_lit |
| | bool_lit | | | bool_lit |
| | ident WS? "=" WS? literal | | | ident WS? "=" WS? literal |
| ; | | ; |
| | | |
| <<< ================= Blocks / Statements ================= >>> | | <<< ================= Blocks / Statements ================= >>> |
| | | |
| block ::= "{" WS? { stmt WS? } "}" ; | | block ::= "{" WS? { stmt WS? } "}" ; |
| | | |
| stmt ::= local_const_stmt stmt_end | | stmt ::= local_const_stmt stmt_end |
| | let_stmt stmt_end | | | let_stmt stmt_end |
| | set_stmt stmt_end | | | set_stmt stmt_end |
| | give_stmt stmt_end | | | give_stmt stmt_end |
| | try_stmt stmt_end | | | try_stmt stmt_end |
| | defer_stmt | | | defer_stmt |
| | asm_stmt stmt_end | | | asm_stmt stmt_end |
| | unsafe_stmt | | | unsafe_stmt |
| | emit_stmt stmt_end | | | emit_stmt stmt_end |
| | assert_stmt stmt_end | | | assert_stmt stmt_end |
| | panic_stmt stmt_end | | | panic_stmt stmt_end |
| | unreachable_stmt stmt_end | | | unreachable_stmt stmt_end |
| | if_stmt | | | if_stmt |
| | while_stmt | | | while_stmt |
| | loop_stmt | | | loop_stmt |
| | for_stmt | | | for_stmt |
| | break_stmt stmt_end | | | break_stmt stmt_end |
| | continue_stmt stmt_end | | | continue_stmt stmt_end |
| | select_stmt | | | select_stmt |
| | match_stmt | | | match_stmt |
| | when_match_stmt | | | when_match_stmt |
| | with_stmt | | | with_stmt |
| | critical_stmt | | | critical_stmt |
| | expr_stmt stmt_end | | | expr_stmt stmt_end |
| ; | | ; |
| | | |
| stmt_end ::= WS? ";" ; | | stmt_end ::= WS? ";" ; |
| | | |
| local_const_stmt ::= "const" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ; | | local_const_stmt ::= "const" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ; |
| let_stmt ::= "let" WS1 [ "mut" WS1 ] pattern [ WS? ":" WS? type_expr ] WS? "=" WS? expr ; | | let_stmt ::= "let" WS1 [ "mut" WS1 ] pattern [ WS? ":" WS? type_expr ] WS? "=" WS? expr ; |
| <<< assign_target stays intentionally syntactic here; projection validity and aliasing | | <<< assign_target stays intentionally syntactic here; projection validity and aliasing |
| are enforced later by sema/typeck/borrowck on structured HIR/MIR places. >>> | | are enforced later by sema/typeck/borrowck on structured HIR/MIR places. >>> |
| set_stmt ::= "set" WS1 assign_target WS? assign_op WS? expr ; | | set_stmt ::= "set" WS1 assign_target WS? assign_op WS? expr ; |
| assign_target ::= unary_expr ; | | assign_target ::= unary_expr ; |
| | | |
| give_stmt ::= "give" [ WS1 expr ] ; | | give_stmt ::= "give" [ WS1 expr ] ; |
| try_stmt ::= "try" WS1 expr ; | | try_stmt ::= "try" WS1 expr ; |
| defer_stmt ::= "defer" WS? block ; | | defer_stmt ::= "defer" WS? block ; |
| | | |
| asm_stmt ::= "asm" WS? "(" WS? asm_arg_list? WS? ")" ; | | asm_stmt ::= "asm" WS? "(" WS? asm_arg_list? WS? ")" ; |
| asm_arg_list ::= asm_arg { WS? "," WS? asm_arg } [ WS? "," ] ; | | asm_arg_list ::= asm_arg { WS? "," WS? asm_arg } [ WS? "," ] ; |
| asm_arg ::= string_lit | ident WS? "(" WS? arg_list? WS? ")" | ident WS? ":" WS? expr ; | | asm_arg ::= string_lit | ident WS? "(" WS? arg_list? WS? ")" | ident WS? ":" WS? expr ; |
| | | |
| unsafe_stmt ::= "unsafe" WS? block ; | | unsafe_stmt ::= "unsafe" WS? block ; |
| | | |
| emit_stmt ::= "emit" WS1 expr ; | | emit_stmt ::= "emit" WS1 expr ; |
| assert_stmt ::= "assert" WS1 expr [ WS? "," WS? expr ] ; | | assert_stmt ::= "assert" WS1 expr [ WS? "," WS? expr ] ; |
| panic_stmt ::= "panic" WS1 expr ; | | panic_stmt ::= "panic" WS1 expr ; |
| unreachable_stmt ::= "unreachable" ; | | unreachable_stmt ::= "unreachable" ; |
| | | |
| if_stmt ::= "if" WS1 expr WS? block | | if_stmt ::= "if" WS1 expr WS? block |
| { WS? "elif" WS1 expr WS? block } | | { WS? "elif" WS1 expr WS? block } |
| [ WS? "else" WS? block ] ; | | [ WS? "else" WS? block ] ; |
| | | |
| while_stmt ::= "while" WS1 expr WS? block ; | | while_stmt ::= "while" WS1 expr WS? block ; |
| loop_stmt ::= "loop" WS? block ; | | loop_stmt ::= "loop" WS? block ; |
| for_stmt ::= "for" WS1 pattern WS1 "in" WS1 expr WS? block ; | | for_stmt ::= "for" WS1 pattern WS1 "in" WS1 expr WS? block ; |
| | | |
| break_stmt ::= "break" [ WS1 expr ] ; | | break_stmt ::= "break" [ WS1 expr ] ; |
| continue_stmt ::= "continue" ; | | continue_stmt ::= "continue" ; |
| | | |
| select_stmt ::= "select" WS1 expr WS? "{" WS? | | select_stmt ::= "select" WS1 expr WS? "{" WS? |
| { "when" WS1 pattern WS? block WS? } | | { "when" WS1 pattern WS? block WS? } |
| [ "else" WS? block ] | | [ "else" WS? block ] |
| WS? "}" ; | | WS? "}" ; |
| | | |
| match_stmt ::= "match" WS1 expr WS? | | match_stmt ::= "match" WS1 expr WS? |
| "{" WS? | | "{" WS? |
| { "case" WS1 pattern [ WS1 "if" WS1 expr ] WS? match_arm_body WS? } | | { "case" WS1 pattern [ WS1 "if" WS1 expr ] WS? match_arm_body WS? } |
| [ WS? "else" WS? match_arm_body ] | | [ WS? "else" WS? match_arm_body ] |
| WS? "}" ; | | WS? "}" ; |
| | | |
| match_arm_body ::= block | "=>" WS? expr WS? ";" ; | | match_arm_body ::= block | "=>" WS? expr WS? ";" ; |
| | | |
| when_match_stmt ::= "when" WS1 expr WS1 "is" WS1 pattern WS? block ; | | when_match_stmt ::= "when" WS1 expr WS1 "is" WS1 pattern WS? block ; |
| with_stmt ::= "with" WS1 expr [ WS1 "as" WS1 pattern ] WS? block ; | | with_stmt ::= "with" WS1 expr [ WS1 "as" WS1 pattern ] WS? block ; |
| critical_stmt ::= "critical" WS? block ; | | critical_stmt ::= "critical" WS? block ; |
| expr_stmt ::= expr ; | | expr_stmt ::= expr ; |
| | | |
| <<< ================= Expressions ================= >>> | | <<< ================= Expressions ================= >>> |
| | | |
| expr ::= assign_expr ; | | expr ::= assign_expr ; |
| | | |
| assign_expr ::= ternary_expr [ WS? assign_op WS? assign_expr ] ; | | assign_expr ::= ternary_expr [ WS? assign_op WS? assign_expr ] ; |
| assign_op ::= "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" ; | | assign_op ::= "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" ; |
| | | |
| ternary_expr ::= coalesce_expr [ WS? "?" WS? expr WS? ":" WS? expr ] ; | | ternary_expr ::= coalesce_expr [ WS? "?" WS? expr WS? ":" WS? expr ] ; |
| coalesce_expr ::= range_expr { WS? "??" WS? range_expr } ; | | coalesce_expr ::= range_expr { WS? "??" WS? range_expr } ; |
| range_expr ::= or_expr [ WS? ( ".." | "..=" ) WS? or_expr ] ; | | range_expr ::= or_expr [ WS? ( ".." | "..=" ) WS? or_expr ] ; |
| | | |
| or_expr ::= and_expr { WS? ( "or" | "||" ) WS? and_expr } ; | | or_expr ::= and_expr { WS? ( "or" | "||" ) WS? and_expr } ; |
| and_expr ::= bit_or_expr { WS? ( "and" | "&&" ) WS? bit_or_expr } ; | | and_expr ::= bit_or_expr { WS? ( "and" | "&&" ) WS? bit_or_expr } ; |
| | | |
| bit_or_expr ::= bit_xor_expr { WS? "|" WS? bit_xor_expr } ; | | bit_or_expr ::= bit_xor_expr { WS? "|" WS? bit_xor_expr } ; |
| bit_xor_expr ::= bit_and_expr { WS? "^" WS? bit_and_expr } ; | | bit_xor_expr ::= bit_and_expr { WS? "^" WS? bit_and_expr } ; |
| bit_and_expr ::= eq_expr { WS? "&" WS? eq_expr } ; | | bit_and_expr ::= eq_expr { WS? "&" WS? eq_expr } ; |
| | | |
| eq_expr ::= rel_expr { WS? ( "==" | "!=" ) WS? rel_expr } ; | | eq_expr ::= rel_expr { WS? ( "==" | "!=" ) WS? rel_expr } ; |
| rel_expr ::= shift_expr { WS? rel_op WS? shift_expr } ; | | rel_expr ::= shift_expr { WS? rel_op WS? shift_expr } ; |
| rel_op ::= "<" | "<=" | ">" | ">=" | "in" | "not" WS1 "in" ; | | rel_op ::= "<" | "<=" | ">" | ">=" | "in" | "not" WS1 "in" ; |
| | | |
| shift_expr ::= add_expr { WS? ( "<<" | ">>" ) WS? add_expr } ; | | shift_expr ::= add_expr { WS? ( "<<" | ">>" ) WS? add_expr } ; |
| add_expr ::= mul_expr { WS? ( "+" | "-" ) WS? mul_expr } ; | | add_expr ::= mul_expr { WS? ( "+" | "-" ) WS? mul_expr } ; |
| mul_expr ::= cast_expr { WS? ( "*" | "/" | "%" ) WS? cast_expr } ; | | mul_expr ::= cast_expr { WS? ( "*" | "/" | "%" ) WS? cast_expr } ; |
| | | |
| cast_expr ::= unary_expr { WS? ( "as" WS? type_expr | "is" WS? pattern | "is" WS1 "not" WS1 pattern ) } ; | | cast_expr ::= unary_expr { WS? ( "as" WS? type_expr | "is" WS? pattern | "is" WS1 "not" WS1 pattern ) } ; |
| | | |
| <<< unary borrow and move syntax are accepted at parse time; whether a use is | | <<< unary borrow and move syntax are accepted at parse time; whether a use is |
| actually a copy or a move is decided later from inferred types. >>> | | actually a copy or a move is decided later from inferred types. >>> |
| unary_expr ::= ( "not" | "-" | "~" | "*" | "&" | "move" | "await" ) WS? unary_expr | | unary_expr ::= ( "not" | "-" | "~" | "*" | "&" | "move" | "await" ) WS? unary_expr |
| | postfix_expr | | | postfix_expr |
| ; | | ; |
| | | |
| <<< postfix chains define the full place surface used later by ownership and | | <<< postfix chains define the full place surface used later by ownership and |
| borrow analysis: field projection, indexing, call, try and await suffixes. >>> | | borrow analysis: field projection, indexing, call, try and await suffixes. >>> |
| postfix_expr ::= primary { call_suffix | member_suffix | index_suffix | try_suffix | await_suffix } ; | | postfix_expr ::= primary { call_suffix | member_suffix | index_suffix | try_suffix | await_suffix } ; |
| call_suffix ::= "(" WS? arg_list? WS? ")" ; | | call_suffix ::= "(" WS? arg_list? WS? ")" ; |
| member_suffix ::= "." ident ; | | member_suffix ::= "." ident ; |
| index_suffix ::= "[" WS? index_expr WS? "]" ; | | index_suffix ::= "[" WS? index_expr WS? "]" ; |
| try_suffix ::= "?" ; | | try_suffix ::= "?" ; |
| await_suffix ::= "." "await" ; | | await_suffix ::= "." "await" ; |
| | | |
| index_expr ::= expr | slice_expr ; | | index_expr ::= expr | slice_expr ; |
| slice_expr ::= [ expr ] ":" [ expr ] [ ":" expr ] ; | | slice_expr ::= [ expr ] ":" [ expr ] [ ":" expr ] ; |
| | | |
| primary ::= literal | | primary ::= literal |
| | builtin_expr | | | builtin_expr |
| | path_expr | | | path_expr |
| | struct_lit | | | struct_lit |
| | list_lit | | | list_lit |
| | tuple_lit | | | tuple_lit |
| | set_lit | | | set_lit |
| | map_lit | | | map_lit |
| | bytes_lit | | | bytes_lit |
| | resource_lit | | | resource_lit |
| | if_expr | | | if_expr |
| | proc_expr | | | proc_expr |
| | match_expr | | | match_expr |
| | lambda_expr | | | lambda_expr |
| | unsafe_expr | | | unsafe_expr |
| | block | | | block |
| | "(" WS? expr WS? ")" | | | "(" WS? expr WS? ")" |
| ; | | ; |
| | | |
| path_expr ::= ident { ( "." | "::" ) ident } ; | | path_expr ::= ident { ( "." | "::" ) ident } ; |
| | | |
| arg_list ::= arg { WS? "," WS? arg } [ WS? "," ] ; | | arg_list ::= arg { WS? "," WS? arg } [ WS? "," ] ; |
| arg ::= ident WS? ":" WS? expr | expr ; | | arg ::= ident WS? ":" WS? expr | expr ; |
| | | |
| tuple_lit ::= "(" WS? expr WS? "," WS? expr { WS? "," WS? expr } [ WS? "," ] WS? ")" ; | | tuple_lit ::= "(" WS? expr WS? "," WS? expr { WS? "," WS? expr } [ WS? "," ] WS? ")" ; |
| set_lit ::= "set" WS? "{" WS? arg_list? WS? "}" ; | | set_lit ::= "set" WS? "{" WS? arg_list? WS? "}" ; |
| | | |
| map_lit ::= "map" WS? "{" WS? map_items? WS? "}" ; | | map_lit ::= "map" WS? "{" WS? map_items? WS? "}" ; |
| map_items ::= map_item { WS? "," WS? map_item } [ WS? "," ] ; | | map_items ::= map_item { WS? "," WS? map_item } [ WS? "," ] ; |
| map_item ::= expr WS? ":" WS? expr ; | | map_item ::= expr WS? ":" WS? expr ; |
| | | |
| bytes_lit ::= "b" string_lit ; | | bytes_lit ::= "b" string_lit ; |
| | | |
| resource_lit ::= "resource" WS? "{" WS? resource_items? WS? "}" ; | | resource_lit ::= "resource" WS? "{" WS? resource_items? WS? "}" ; |
| resource_items ::= resource_item { WS? "," WS? resource_item } [ WS? "," ] ; | | resource_items ::= resource_item { WS? "," WS? resource_item } [ WS? "," ] ; |
| resource_item ::= ident WS? ":" WS? expr ; | | resource_item ::= ident WS? ":" WS? expr ; |
| | | |
| struct_lit ::= type_path WS? "{" WS? field_init_list? WS? "}" ; | | struct_lit ::= type_path WS? "{" WS? field_init_list? WS? "}" ; |
| type_path ::= ident { ( "." | "::" ) ident } ; | | type_path ::= ident { ( "." | "::" ) ident } ; |
| field_init_list ::= field_init { WS? "," WS? field_init } [ WS? "," ] ; | | field_init_list ::= field_init { WS? "," WS? field_init } [ WS? "," ] ; |
| field_init ::= ident WS? ":" WS? expr | | field_init ::= ident WS? ":" WS? expr |
| | ident | | | ident |
| | ".." expr | | | ".." expr |
| ; | | ; |
| | | |
| if_expr ::= "if" WS1 expr WS? block | | if_expr ::= "if" WS1 expr WS? block |
| { WS? "elif" WS1 expr WS? block } | | { WS? "elif" WS1 expr WS? block } |
| [ WS? "else" WS? block ] ; | | [ WS? "else" WS? block ] ; |
| | | |
| proc_expr ::= { attr_prefix WS? } proc_modifier* "proc" WS? "(" WS? param_list? WS? ")" | | proc_expr ::= { attr_prefix WS? } proc_modifier* "proc" WS? "(" WS? param_list? WS? ")" |
| [ WS? "->" WS? type_expr ] | | [ WS? "->" WS? type_expr ] |
| WS? proc_suffix* | | WS? proc_suffix* |
| WS? block ; | | WS? block ; |
| | | |
| match_expr ::= "match" WS1 expr WS? | | match_expr ::= "match" WS1 expr WS? |
| "{" WS? | | "{" WS? |
| { "case" WS1 pattern [ WS1 "if" WS1 expr ] WS? match_arm_body WS? } | | { "case" WS1 pattern [ WS1 "if" WS1 expr ] WS? match_arm_body WS? } |
| [ WS? "else" WS? match_arm_body ] | | [ WS? "else" WS? match_arm_body ] |
| WS? "}" ; | | WS? "}" ; |
| | | |
| lambda_expr ::= "|" WS? param_list? WS? "|" WS? ( expr | block ) ; | | lambda_expr ::= "|" WS? param_list? WS? "|" WS? ( expr | block ) ; |
| unsafe_expr ::= "unsafe" WS? block ; | | unsafe_expr ::= "unsafe" WS? block ; |
| | | |
| builtin_expr ::= sizeof_expr | alignof_expr | offsetof_expr | typeof_expr | nameof_expr ; | | builtin_expr ::= sizeof_expr | alignof_expr | offsetof_expr | typeof_expr | nameof_expr ; |
| sizeof_expr ::= "sizeof" WS? "(" WS? ( type_expr | expr ) WS? ")" ; | | sizeof_expr ::= "sizeof" WS? "(" WS? ( type_expr | expr ) WS? ")" ; |
| alignof_expr ::= "alignof" WS? "(" WS? type_expr WS? ")" ; | | alignof_expr ::= "alignof" WS? "(" WS? type_expr WS? ")" ; |
| offsetof_expr ::= "offsetof" WS? "(" WS? type_expr WS? "," WS? ident WS? ")" ; | | offsetof_expr ::= "offsetof" WS? "(" WS? type_expr WS? "," WS? ident WS? ")" ; |
| typeof_expr ::= "typeof" WS? "(" WS? expr WS? ")" ; | | typeof_expr ::= "typeof" WS? "(" WS? expr WS? ")" ; |
| nameof_expr ::= "nameof" WS? "(" WS? path_expr WS? ")" ; | | nameof_expr ::= "nameof" WS? "(" WS? path_expr WS? ")" ; |
| | | |
| <<< ================= Patterns ================= >>> | | <<< ================= Patterns ================= >>> |
| | | |
| pattern ::= pattern_or ; | | pattern ::= pattern_or ; |
| pattern_or ::= pattern_atom { WS? "|" WS? pattern_atom } ; | | pattern_or ::= pattern_atom { WS? "|" WS? pattern_atom } ; |
| | | |
| pattern_atom ::= "_" | | pattern_atom ::= "_" |
| | literal | | | literal |
| | "mut" WS1 pattern_bind | | | "mut" WS1 pattern_bind |
| | "ref" WS1 pattern_bind | | | "ref" WS1 pattern_bind |
| | pattern_bind | | | pattern_bind |
| | pattern_ctor | | | pattern_ctor |
| | pattern_struct | | | pattern_struct |
| | pattern_tuple | | | pattern_tuple |
| | pattern_list | | | pattern_list |
| | pattern_range | | | pattern_range |
| ; | | ; |
| | | |
| pattern_bind ::= ident ; | | pattern_bind ::= ident ; |
| pattern_ctor ::= pattern_head [ "(" WS? pattern_args? WS? ")" ] ; | | pattern_ctor ::= pattern_head [ "(" WS? pattern_args? WS? ")" ] ; |
| pattern_head ::= ident { ( "." | "::" ) ident } ; | | pattern_head ::= ident { ( "." | "::" ) ident } ; |
| pattern_args ::= pattern { WS? "," WS? pattern } [ WS? "," ] ; | | pattern_args ::= pattern { WS? "," WS? pattern } [ WS? "," ] ; |
| | | |
| pattern_struct ::= pattern_head WS? "{" WS? pattern_fields? WS? "}" ; | | pattern_struct ::= pattern_head WS? "{" WS? pattern_fields? WS? "}" ; |
| pattern_fields ::= pattern_field { WS? "," WS? pattern_field } [ WS? "," ] ; | | pattern_fields ::= pattern_field { WS? "," WS? pattern_field } [ WS? "," ] ; |
| pattern_field ::= ident [ WS? ":" WS? pattern ] | ".." ; | | pattern_field ::= ident [ WS? ":" WS? pattern ] | ".." ; |
| | | |
| pattern_tuple ::= "(" WS? pattern WS? "," WS? pattern { WS? "," WS? pattern } [ WS? "," ] WS? ")" ; | | pattern_tuple ::= "(" WS? pattern WS? "," WS? pattern { WS? "," WS? pattern } [ WS? "," ] WS? ")" ; |
| pattern_list ::= "[" WS? pattern_args? WS? "]" ; | | pattern_list ::= "[" WS? pattern_args? WS? "]" ; |
| pattern_range ::= literal WS? ( ".." | "..=" ) WS? literal ; | | pattern_range ::= literal WS? ( ".." | "..=" ) WS? literal ; |
| | | |
| <<< ================= Types ================= >>> | | <<< ================= Types ================= >>> |
| | | |
| type_expr ::= type_union ; | | type_expr ::= type_union ; |
| | | |
| type_union ::= type_prefix { WS? "|" WS? type_prefix } ; | | type_union ::= type_prefix { WS? "|" WS? type_prefix } ; |
| | | |
| type_prefix ::= type_qualifier* type_atom ; | | type_prefix ::= type_qualifier* type_atom ; |
| type_qualifier ::= type_qual WS1 | addr_space WS1 ; | | type_qualifier ::= type_qual WS1 | addr_space WS1 ; |
| | | |
| type_qual ::= "const" | "volatile" | "atomic" | "mut" | "owned" | "borrow" ; | | type_qual ::= "const" | "volatile" | "atomic" | "mut" | "owned" | "borrow" ; |
| addr_space ::= "user" | "kernel" | "phys" | "mmio" | "dma" ; | | addr_space ::= "user" | "kernel" | "phys" | "mmio" | "dma" ; |
| | | |
| type_atom ::= reference_type | | type_atom ::= reference_type |
| | pointer_type | | | pointer_type |
| | optional_type | | | optional_type |
| | fixed_array_type | | | fixed_array_type |
| | slice_type | | | slice_type |
| | tuple_type | | | tuple_type |
| | proc_type | | | proc_type |
| | dyn_type | | | dyn_type |
| | impl_trait_type | | | impl_trait_type |
| | type_primary | | | type_primary |
| ; | | ; |
| | | |
| <<< shared and mutable references are part of the core surface grammar; lifetime, | | <<< shared and mutable references are part of the core surface grammar; lifetime, |
| aliasing and region closure remain semantic checks outside the parser. >>> | | aliasing and region closure remain semantic checks outside the parser. >>> |
| reference_type ::= "&" WS? [ lifetime WS? ] [ "mut" WS1 ] type_expr ; | | reference_type ::= "&" WS? [ lifetime WS? ] [ "mut" WS1 ] type_expr ; |
| pointer_type ::= "*" WS? [ "const" WS1 | "mut" WS1 | "volatile" WS1 | addr_space WS1 ] type_expr ; | | pointer_type ::= "*" WS? [ "const" WS1 | "mut" WS1 | "volatile" WS1 | addr_space WS1 ] type_expr ; |
| optional_type ::= "?" WS? type_expr ; | | optional_type ::= "?" WS? type_expr ; |
| | | |
| fixed_array_type ::= "[" WS? type_expr WS? ";" WS? expr WS? "]" ; | | fixed_array_type ::= "[" WS? type_expr WS? ";" WS? expr WS? "]" ; |
| slice_type ::= "[" WS? type_expr WS? "]" ; | | slice_type ::= "[" WS? type_expr WS? "]" ; |
| | | |
| tuple_type ::= "(" WS? type_expr WS? "," WS? type_expr { WS? "," WS? type_expr } [ WS? "," ] WS? ")" ; | | tuple_type ::= "(" WS? type_expr WS? "," WS? type_expr { WS? "," WS? type_expr } [ WS? "," ] WS? ")" ; |
| proc_type ::= "proc" WS? "(" WS? type_list? WS? ")" [ WS? "->" WS? type_expr ] ; | | proc_type ::= "proc" WS? "(" WS? type_list? WS? ")" [ WS? "->" WS? type_expr ] ; |
| | | |
| type_list ::= type_param { WS? "," WS? type_param } [ WS? "," ] ; | | type_list ::= type_param { WS? "," WS? type_param } [ WS? "," ] ; |
| type_param ::= ident WS? ":" WS? type_expr | type_expr ; | | type_param ::= ident WS? ":" WS? type_expr | type_expr ; |
| | | |
| dyn_type ::= "dyn" WS1 trait_bound ; | | dyn_type ::= "dyn" WS1 trait_bound ; |
| impl_trait_type ::= "impl" WS1 trait_bound ; | | impl_trait_type ::= "impl" WS1 trait_bound ; |
| | | |
| type_primary ::= type_path [ "[" WS? type_list? WS? "]" ] | | type_primary ::= type_path [ "[" WS? type_list? WS? "]" ] |
| | primitive_type | | | primitive_type |
| | "Self" | | | "Self" |
| ; | | ; |
| | | |
| lifetime ::= "'" ident ; | | lifetime ::= "'" ident ; |
| | | |
| primitive_type ::= "void" | | primitive_type ::= "void" |
| | "never" | | | "never" |
| | "unit" | | | "unit" |
| | "bool" | | | "bool" |
| | "char" | | | "char" |
| | "rune" | | | "rune" |
| | "str" | | | "str" |
| | "string" | | | "string" |
| | "bytes" | | | "bytes" |
| | "cstr" | | | "cstr" |
| | "int" | | | "int" |
| | "i8" | "i16" | "i32" | "i64" | "i128" | | | "i8" | "i16" | "i32" | "i64" | "i128" |
| | "u8" | "u16" | "u32" | "u64" | "u128" | | | "u8" | "u16" | "u32" | "u64" | "u128" |
| | "usize" | "isize" | | | "usize" | "isize" |
| | "intptr" | "uintptr" | | | "intptr" | "uintptr" |
| | "f16" | "f32" | "f64" | "f128" | | | "f16" | "f32" | "f64" | "f128" |
| | "c_char" | "c_int" | "c_uint" | "c_long" | "c_ulong" | "c_void" | | | "c_char" | "c_int" | "c_uint" | "c_long" | "c_ulong" | "c_void" |
| | "TokenId" | | | "TokenId" |
| | "NodeId" | | | "NodeId" |
| | "DefId" | | | "DefId" |
| | "HirId" | | | "HirId" |
| | "MirId" | | | "MirId" |
| | "TypeId" | | | "TypeId" |
| | "SymbolId" | | | "SymbolId" |
| | "ScopeId" | | | "ScopeId" |
| | "BlockId" | | | "BlockId" |
| | "ValueId" | | | "ValueId" |
| | "InstrId" | | | "InstrId" |
| ; | | ; |
| | | |
| <<< ================= Literals ================= >>> | | <<< ================= Literals ================= >>> |
| | | |
| literal ::= bool_lit | | literal ::= bool_lit |
| | null_lit | | | null_lit |
| | int_lit | | | int_lit |
| | float_lit | | | float_lit |
| | char_lit | | | char_lit |
| | string_lit | | | string_lit |
| | list_lit | | | list_lit |
| ; | | ; |
| | | |
| list_lit ::= "[" WS? ( list_comp | arg_list? ) WS? "]" ; | | list_lit ::= "[" WS? ( list_comp | arg_list? ) WS? "]" ; |
| list_comp ::= expr WS1 "for" WS1 pattern WS1 "in" WS1 expr [ WS1 "if" WS1 expr ] ; | | list_comp ::= expr WS1 "for" WS1 pattern WS1 "in" WS1 expr [ WS1 "if" WS1 expr ] ; |
| | | |
| bool_lit ::= "true" | "false" ; | | bool_lit ::= "true" | "false" ; |
| null_lit ::= "null" ; | | null_lit ::= "null" ; |
| | | |
| int_lit ::= [ "-" ] DIGIT { DIGIT | "_" } [ suffix ] | | int_lit ::= [ "-" ] DIGIT { DIGIT | "_" } [ suffix ] |
| | [ "-" ] "0x" HEXDIGIT { HEXDIGIT | "_" } [ suffix ] | | | [ "-" ] "0x" HEXDIGIT { HEXDIGIT | "_" } [ suffix ] |
| | [ "-" ] "0b" BINDIGIT { BINDIGIT | "_" } [ suffix ] | | | [ "-" ] "0b" BINDIGIT { BINDIGIT | "_" } [ suffix ] |
| | [ "-" ] "0o" OCTDIGIT { OCTDIGIT | "_" } [ suffix ] | | | [ "-" ] "0o" OCTDIGIT { OCTDIGIT | "_" } [ suffix ] |
| ; | | ; |
| | | |
| float_lit ::= [ "-" ] DIGIT { DIGIT | "_" } "." DIGIT { DIGIT | "_" } [ exponent ] [ suffix ] ; | | float_lit ::= [ "-" ] DIGIT { DIGIT | "_" } "." DIGIT { DIGIT | "_" } [ exponent ] [ suffix ] ; |
| exponent ::= ( "e" | "E" ) [ "+" | "-" ] DIGIT { DIGIT | "_" } ; | | exponent ::= ( "e" | "E" ) [ "+" | "-" ] DIGIT { DIGIT | "_" } ; |
| | | |
| char_lit ::= "'" char_char "'" ; | | char_lit ::= "'" char_char "'" ; |
| char_char ::= escape_seq | ~"'" ; | | char_char ::= escape_seq | ~"'" ; |
| | | |
| string_lit ::= "\"" { string_char } "\"" | raw_string_lit ; | | string_lit ::= "\"" { string_char } "\"" | raw_string_lit ; |
| string_char ::= escape_seq | ~"\"" ; | | string_char ::= escape_seq | ~"\"" ; |
| | | |
| escape_seq ::= "\\n" | | escape_seq ::= "\\n" |
| | "\\r" | | | "\\r" |
| | "\\t" | | | "\\t" |
| | "\\0" | | | "\\0" |
| | "\\\"" | | | "\\\"" |
| | "\\'" | | | "\\'" |
| | "\\\\" | | | "\\\\" |
| | "\\x" HEXDIGIT HEXDIGIT | | | "\\x" HEXDIGIT HEXDIGIT |
| | "\\u{" HEXDIGIT { HEXDIGIT } "}" | | | "\\u{" HEXDIGIT { HEXDIGIT } "}" |
| ; | | ; |
| | | |
| raw_string_lit ::= "\"\"\"" { raw_string_char } "\"\"\"" | | raw_string_lit ::= "\"\"\"" { raw_string_char } "\"\"\"" |
| | "r\"" { raw_string_char } "\"" | | | "r\"" { raw_string_char } "\"" |
| ; | | ; |
| raw_string_char ::= ~"\"\"\"" ; | | raw_string_char ::= ~"\"\"\"" ; |
| | | |
| <<< ================= Lexical ================= >>> | | <<< ================= Lexical ================= >>> |
| | | |
| line_comment ::= "#" { ~NEWLINE ANY } | | line_comment ::= "#" { ~NEWLINE ANY } |
| | "//" { ~NEWLINE ANY } | | | "//" { ~NEWLINE ANY } |
| ; | | ; |
| | | |
| block_comment ::= "/*" { ~"*/" ANY } "*/" ; | | block_comment ::= "/*" { ~"*/" ANY } "*/" ; |
| zone_comment ::= "<<<" { ~">>>" ANY } ">>>" ; | | zone_comment ::= "<<<" { ~">>>" ANY } ">>>" ; |
| | | |
| ident ::= ( LETTER | "_" ) { LETTER | DIGIT | "_" } ; | | ident ::= ( LETTER | "_" ) { LETTER | DIGIT | "_" } ; |
| suffix ::= LETTER { LETTER | DIGIT } ; | | suffix ::= LETTER { LETTER | DIGIT } ; |
| | | |
| WS ::= { " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment } ; | | WS ::= { " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment } ; |
| WS1 ::= ( " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment ) | | WS1 ::= ( " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment ) |
| { " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment } ; | | { " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment } ; |
| | | |
| NEWLINE ::= "\n" | "\r\n" ; | | NEWLINE ::= "\n" | "\r\n" ; |
| | | |
| LETTER ::= "a"..."z" | "A"..."Z" ; | | LETTER ::= "a"..."z" | "A"..."Z" ; |
| DIGIT ::= "0"..."9" ; | | DIGIT ::= "0"..."9" ; |
| BINDIGIT ::= "0" | "1" ; | | BINDIGIT ::= "0" | "1" ; |
| OCTDIGIT ::= "0"..."7" ; | | OCTDIGIT ::= "0"..."7" ; |
| HEXDIGIT ::= DIGIT | "a"..."f" | "A"..."F" ; | | HEXDIGIT ::= DIGIT | "a"..."f" | "A"..."F" ; |
| | | |
| EOF ::= !ANY ; | | EOF ::= !ANY ; |