Vitte EBNF Memory Guide (EN)

Source of truth: src/vitte/grammar/vitte.ebnf.

Checksum (SHA-256): 4493876f55f9d93e4b5dd3dccc15a337693deb68955e9952648866ba8a8230f6

Prompt Contract

  1. Use only this grammar as source of truth.
  2. If unsure, answer: unknown.
  3. Validate rule by rule with production names.
  4. Return compliant/non-compliant with evidence.
  5. Provide minimal valid/invalid examples per rule.
<<< =========================================================
   Vitte — Complete Core Grammar
   systems + application + kernel + compiler surface
   canonical blocks: { }
   canonical syntax source for parser/docs/tests
   low-level capable
   compiler-capable
   no aliases, reduced duplicates
   ========================================================= >>>

program ::= WS? { toplevel WS? } EOF ;

<<< ================= Top-level ================= >>>

toplevel ::= inner_attribute
          | space_decl
          | use_decl
          | export_decl
          | const_decl
          | static_decl
          | global_decl
          | type_alias_decl
          | opaque_type_decl
          | extern_type_decl
          | form_decl
          | class_decl
          | union_decl
          | bits_decl
          | pick_decl
          | flags_decl
          | trait_decl
          | impl_decl
          | extern_block
          | proc_decl
          | intrinsic_decl
          | compiler_decl
          | query_decl
          | pass_decl
          | backend_decl
          | diagnostic_decl
          | macro_decl
          | comptime_decl
          | static_assert_decl
          | test_decl
          | bench_decl
          | entry_decl
          ;

space_decl ::= "space" WS1 module_path ;

use_decl ::= "use" WS1 package_path [ use_group | use_glob ] [ WS1 "as" WS1 ident ] ;
use_glob ::= "." "*" ;
use_group ::= "." "{" WS? ( "*" | import_items [ WS? "," WS? "*" ]? ) WS? "}" ;

import_items ::= import_item { WS? "," WS? import_item } [ WS? "," ] ;
import_item ::= ident [ WS1 "as" WS1 ident ] ;

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 ;
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 ;

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 ] ;
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? "}" ;
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? "}" ;

form_items ::= form_item { WS? ","? WS? form_item } [ WS? "," ] ;
form_item ::= field_item | const_decl | type_alias_decl | proc_decl ;

class_items ::= class_item { WS? ","? WS? class_item } [ WS? "," ] ;
class_item ::= field_item | const_decl | type_alias_decl | proc_decl ;

field_list ::= field_item { WS? "," WS? field_item } [ WS? "," ] ;
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? "}" ;
bitfield_list ::= bitfield_item { WS? "," WS? bitfield_item } [ WS? "," ] ;
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? "{" WS? case_list? WS? "}" ;
case_list ::= case_item { WS? "," WS? case_item } [ WS? "," ] ;
case_item ::= [ "case" WS1 ] ident [ "(" WS? case_payload? WS? ")" ] [ WS? "=" WS? expr ] ;
case_payload ::= case_field { WS? "," WS? case_field } [ WS? "," ] ;
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? "}" ;
flag_list ::= flag_item { WS? "," WS? flag_item } [ WS? "," ] ;
flag_item ::= ident [ WS? "=" WS? expr ] ;

trait_decl ::= { attr_prefix WS? } [ "unsafe" WS1 ] "trait" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? trait_item* WS? "}" ;
trait_item ::= proc_signature | const_decl | associated_type_decl ;

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_head ::= type_expr | type_expr WS1 "for" WS1 type_expr ;
impl_item ::= const_decl | type_alias_decl | associated_type_decl | proc_decl ;

proc_signature ::= { attr_prefix WS? } "proc" WS1 ident [ generic_params ]
                   "(" WS? param_list? WS? ")"
                   [ WS? "->" WS? type_expr ]
                   WS? proc_suffix*
                   WS? ";"
                   ;

proc_decl ::= { attr_prefix WS? } [ visibility WS1 ] proc_modifier* [ extern_clause WS1 ] "proc" WS1 proc_name [ generic_params ]
              "(" WS? param_list? WS? ")"
              [ WS? "->" WS? type_expr ]
              WS? proc_suffix*
              WS? ( block | ";" )
              ;

proc_name ::= ident | "operator" WS? operator_symbol ;
operator_symbol ::= "+" | "-" | "*" | "/" | "%"
                  | "==" | "!=" | "<" | "<=" | ">" | ">="
                  | "[]" | "()" ;

proc_modifier ::= "async" WS1
                | "unsafe" WS1
                | "const" WS1
                | "inline" WS1
                | "noinline" WS1
                | "naked" WS1
                | "interrupt" WS1
                ;

proc_suffix ::= effects_clause
              | requires_clause
              | where_clause
              | "noexcept"
              ;

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_proc_decl ::= { attr_prefix WS? } "proc" WS1 ident [ generic_params ]
                     "(" WS? param_list? WS? ")"
                     [ WS? "->" WS? type_expr ]
                     WS? proc_suffix*
                     WS? ";"
                     ;

extern_clause ::= "extern" WS1 extern_abi ;
extern_abi ::= callconv | string_lit ;
callconv ::= "C" | "sysv64" | "win64" | "interrupt" | "naked" ;

intrinsic_decl ::= { attr_prefix WS? } "intrinsic" WS1 ident [ generic_params ]
                   "(" WS? param_list? WS? ")"
                   [ WS? "->" WS? type_expr ]
                   WS? ";"
                   ;

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 ::= ident [ WS? ":" WS? macro_kind ] ;
macro_kind ::= "expr" | "stmt" | "type" | "ident" | "block" | "item" ;

comptime_decl ::= "comptime" WS? block ;
static_assert_decl ::= "static_assert" WS? "(" WS? expr [ WS? "," WS? expr ] WS? ")" ;
test_decl ::= { attr_prefix WS? } "test" 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 ;

visibility ::= "pub" | "priv" | "pub" WS? "(" WS? visibility_scope WS? ")" ;
visibility_scope ::= "package" | "module" | "super" ;

generic_params ::= "[" WS? generic_param_list? WS? "]" ;
generic_param_list ::= generic_param { WS? "," WS? generic_param } [ WS? "," ] ;
generic_param ::= ident [ WS? ":" WS? trait_bound ] [ WS? "=" WS? type_expr ]
                | "const" WS1 ident WS? ":" WS? type_expr
                | "comptime" WS1 ident WS? ":" WS? type_expr
                ;

where_clause ::= "where" WS1 where_bounds ;
where_bounds ::= where_bound { WS? "," WS? where_bound } [ WS? "," ] ;
where_bound ::= type_expr WS? ":" WS? trait_bound
              | type_expr WS? "==" WS? type_expr
              | expr WS? rel_op WS? expr
              ;

trait_bound ::= type_expr { WS? "+" WS? type_expr } ;

param_list ::= param { WS? "," WS? param } [ WS? "," ] ;
param ::= self_param | normal_param | variadic_param ;
self_param ::= [ "&" WS? ] [ "mut" WS1 ] "self" ;
normal_param ::= [ param_mode WS1 ] pattern [ WS? ":" WS? type_expr ] [ WS? "=" WS? expr ] ;
variadic_param ::= "..." | ident WS? ":" WS? "..." type_expr ;
param_mode ::= "mut" | "owned" | "borrow" | "move" ;

effects_clause ::= "effects" WS? "(" WS? ident_list? WS? ")" ;
requires_clause ::= "requires" WS? "(" WS? capability_list? WS? ")" ;
capability_list ::= capability { WS? "," WS? capability } [ WS? "," ] ;
capability ::= ident { "." ident } ;

module_path ::= relative? package_parts ;
package_path ::= relative? package_parts ;
relative ::= { "." } ;
package_parts ::= ident { ( "/" | "." | "::" ) ident } ;
ident_list ::= ident { WS? "," WS? ident } [ WS? "," ] ;

<<< ================= Compiler Declarations ================= >>>

compiler_decl ::= { attr_prefix WS? } "compiler" WS1 ident WS? "{" WS? compiler_items? WS? "}" ;
compiler_items ::= compiler_item { WS? compiler_item } ;

compiler_item ::= compiler_phase_decl
                | compiler_stage_decl
                | compiler_artifact_decl
                | compiler_pipeline_decl
                | compiler_cache_decl
                | compiler_target_decl
                ;

compiler_phase_decl ::= "phase" WS1 ident WS? "{" WS?
                        "input" WS? ":" WS? type_expr WS? ";"
                        "output" WS? ":" WS? type_expr WS? ";"
                        [ "errors" WS? ":" WS? type_expr WS? ";" ]
                        WS? "}" ;

compiler_stage_decl ::= "stage" WS1 ident WS? ":" WS? ident_list WS? ";" ;
compiler_artifact_decl ::= "artifact" WS1 ident WS? ":" WS? type_expr WS? ";" ;

compiler_pipeline_decl ::= "pipeline" WS1 ident WS? "{" WS? pipeline_step* WS? "}" ;
pipeline_step ::= "run" WS1 ident [ WS? "as" WS? ident ] WS? ";"
                | "dump" WS1 ident WS? ";"
                | "verify" WS1 ident WS? ";"
                ;

compiler_cache_decl ::= "cache" WS1 ident WS? "{" WS? cache_item* WS? "}" ;
cache_item ::= "key" WS? ":" WS? type_expr WS? ";"
             | "value" WS? ":" WS? type_expr WS? ";"
             | "strategy" WS? ":" WS? ident WS? ";"
             ;

compiler_target_decl ::= "target" WS1 ident WS? "{" WS? target_item* WS? "}" ;
target_item ::= ident WS? ":" WS? expr WS? ";" ;

query_decl ::= { attr_prefix WS? } "query" WS1 ident
               "(" WS? param_list? WS? ")"
               WS? "->" WS? type_expr
               WS? query_body ;

query_body ::= block | ";" ;

pass_decl ::= { attr_prefix WS? } "pass" WS1 ident WS? "{" WS? pass_items? WS? "}" ;
pass_items ::= pass_item { WS? pass_item } ;
pass_item ::= "input" WS? ":" WS? type_expr WS? ";"
            | "output" WS? ":" WS? type_expr WS? ";"
            | "requires" WS? ":" WS? ident_list WS? ";"
            | "invalidates" WS? ":" WS? ident_list WS? ";"
            | proc_decl
            ;

backend_decl ::= { attr_prefix WS? } "backend" WS1 ident WS? "{" WS? backend_items? WS? "}" ;
backend_items ::= backend_item { WS? backend_item } ;
backend_item ::= "target" WS? ":" WS? string_lit WS? ";"
               | "format" WS? ":" WS? backend_format WS? ";"
               | "emits" WS? ":" WS? backend_output WS? ";"
               | "requires" WS? ":" WS? ident_list WS? ";"
               | proc_decl
               ;

backend_format ::= "c" | "llvm" | "asm" | "object" | "wasm" | "ir" ;
backend_output ::= "source" | "assembly" | "object" | "executable" | "library" ;

diagnostic_decl ::= { attr_prefix WS? } "diagnostic" WS1 diagnostic_code WS? "{" WS? diagnostic_items? WS? "}" ;
diagnostic_code ::= ident | string_lit ;
diagnostic_items ::= diagnostic_item { WS? diagnostic_item } ;

diagnostic_item ::= "level" WS? ":" WS? diagnostic_level WS? ";"
                  | "message" WS? ":" WS? string_lit WS? ";"
                  | "label" WS? ":" WS? string_lit WS? ";"
                  | "help" WS? ":" WS? string_lit WS? ";"
                  | "note" WS? ":" WS? string_lit WS? ";"
                  | "suggest" WS? ":" WS? string_lit WS? ";"
                  ;

diagnostic_level ::= "error" | "warning" | "note" | "help" | "fatal" ;

<<< ================= Attributes ================= >>>

attr_prefix ::= outer_attribute | doc_comment | docstring ;
inner_attribute ::= "#![" attr_path [ "(" WS? attr_arg_list? WS? ")" ] "]" ;
outer_attribute ::= "#[" attr_path [ "(" WS? attr_arg_list? WS? ")" ] "]" ;
doc_comment ::= "///" { ~NEWLINE ANY } ;
docstring ::= raw_string_lit ;

attr_path ::= ident { "." ident } ;
attr_arg_list ::= attr_arg { WS? "," WS? attr_arg } [ WS? "," ] ;
attr_arg ::= ident
           | string_lit
           | int_lit
           | bool_lit
           | ident WS? "=" WS? literal
           ;

<<< ================= Blocks / Statements ================= >>>

block ::= "{" WS? { stmt WS? } "}" ;

stmt ::= local_const_stmt stmt_end
       | let_stmt stmt_end
       | set_stmt stmt_end
       | give_stmt stmt_end
       | try_stmt stmt_end
       | defer_stmt
       | asm_stmt stmt_end
       | unsafe_stmt
       | emit_stmt stmt_end
       | assert_stmt stmt_end
       | panic_stmt stmt_end
       | unreachable_stmt stmt_end
       | if_stmt
       | while_stmt
       | loop_stmt
       | for_stmt
       | break_stmt stmt_end
       | continue_stmt stmt_end
       | select_stmt
       | match_stmt
       | when_match_stmt
       | with_stmt
       | critical_stmt
       | expr_stmt stmt_end
       ;

stmt_end ::= WS? ";" ;

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 ;
<<< assign_target stays intentionally syntactic here; projection validity and aliasing
    are enforced later by sema/typeck/borrowck on structured HIR/MIR places. >>>
set_stmt ::= "set" WS1 assign_target WS? assign_op WS? expr ;
assign_target ::= unary_expr ;

give_stmt ::= "give" [ WS1 expr ] ;
try_stmt ::= "try" WS1 expr ;
defer_stmt ::= "defer" WS? block ;

asm_stmt ::= "asm" WS? "(" WS? asm_arg_list? 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 ;

unsafe_stmt ::= "unsafe" WS? block ;

emit_stmt ::= "emit" WS1 expr ;
assert_stmt ::= "assert" WS1 expr [ WS? "," WS? expr ] ;
panic_stmt ::= "panic" WS1 expr ;
unreachable_stmt ::= "unreachable" ;

if_stmt ::= "if" WS1 expr WS? block
            { WS? "elif" WS1 expr WS? block }
            [ WS? "else" WS? block ] ;

while_stmt ::= "while" WS1 expr WS? block ;
loop_stmt ::= "loop" WS? block ;
for_stmt ::= "for" WS1 pattern WS1 "in" WS1 expr WS? block ;

break_stmt ::= "break" [ WS1 expr ] ;
continue_stmt ::= "continue" ;

select_stmt ::= "select" WS1 expr WS? "{" WS?
                { "when" WS1 pattern WS? block WS? }
                [ "else" WS? block ]
                WS? "}" ;

match_stmt ::= "match" WS1 expr WS?
               "{" WS?
               { "case" WS1 pattern [ WS1 "if" WS1 expr ] WS? match_arm_body WS? }
               [ WS? "else" WS? match_arm_body ]
               WS? "}" ;

match_arm_body ::= block | "=>" WS? expr WS? ";" ;

when_match_stmt ::= "when" WS1 expr WS1 "is" WS1 pattern WS? block ;
with_stmt ::= "with" WS1 expr [ WS1 "as" WS1 pattern ] WS? block ;
critical_stmt ::= "critical" WS? block ;
expr_stmt ::= expr ;

<<< ================= Expressions ================= >>>

expr ::= assign_expr ;

assign_expr ::= ternary_expr [ WS? assign_op WS? assign_expr ] ;
assign_op ::= "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" ;

ternary_expr ::= coalesce_expr [ WS? "?" WS? expr WS? ":" WS? expr ] ;
coalesce_expr ::= range_expr { WS? "??" WS? range_expr } ;
range_expr ::= or_expr [ WS? ( ".." | "..=" ) WS? or_expr ] ;

or_expr ::= and_expr { WS? ( "or" | "||" ) WS? and_expr } ;
and_expr ::= bit_or_expr { WS? ( "and" | "&&" ) WS? bit_or_expr } ;

bit_or_expr ::= bit_xor_expr { WS? "|" WS? bit_xor_expr } ;
bit_xor_expr ::= bit_and_expr { WS? "^" WS? bit_and_expr } ;
bit_and_expr ::= eq_expr { WS? "&" WS? eq_expr } ;

eq_expr ::= rel_expr { WS? ( "==" | "!=" ) WS? rel_expr } ;
rel_expr ::= shift_expr { WS? rel_op WS? shift_expr } ;
rel_op ::= "<" | "<=" | ">" | ">=" | "in" | "not" WS1 "in" ;

shift_expr ::= add_expr { WS? ( "<<" | ">>" ) WS? add_expr } ;
add_expr ::= mul_expr { WS? ( "+" | "-" ) WS? mul_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 ) } ;

<<< 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. >>>
unary_expr ::= ( "not" | "-" | "~" | "*" | "&" | "move" | "await" ) WS? unary_expr
             | postfix_expr
             ;

<<< postfix chains define the full place surface used later by ownership and
    borrow analysis: field projection, indexing, call, try and await suffixes. >>>
postfix_expr ::= primary { call_suffix | member_suffix | index_suffix | try_suffix | await_suffix } ;
call_suffix ::= "(" WS? arg_list? WS? ")" ;
member_suffix ::= "." ident ;
index_suffix ::= "[" WS? index_expr WS? "]" ;
try_suffix ::= "?" ;
await_suffix ::= "." "await" ;

index_expr ::= expr | slice_expr ;
slice_expr ::= [ expr ] ":" [ expr ] [ ":" expr ] ;

primary ::= literal
          | builtin_expr
          | path_expr
          | struct_lit
          | list_lit
          | tuple_lit
          | set_lit
          | map_lit
          | bytes_lit
          | resource_lit
          | if_expr
          | proc_expr
          | match_expr
          | lambda_expr
          | unsafe_expr
          | block
          | "(" WS? expr WS? ")"
          ;

path_expr ::= ident { ( "." | "::" ) ident } ;

arg_list ::= arg { WS? "," WS? arg } [ WS? "," ] ;
arg ::= ident WS? ":" WS? expr | expr ;

tuple_lit ::= "(" WS? expr WS? "," WS? expr { WS? "," WS? expr } [ WS? "," ] WS? ")" ;
set_lit ::= "set" WS? "{" WS? arg_list? WS? "}" ;

map_lit ::= "map" WS? "{" WS? map_items? WS? "}" ;
map_items ::= map_item { WS? "," WS? map_item } [ WS? "," ] ;
map_item ::= expr WS? ":" WS? expr ;

bytes_lit ::= "b" string_lit ;

resource_lit ::= "resource" WS? "{" WS? resource_items? WS? "}" ;
resource_items ::= resource_item { WS? "," WS? resource_item } [ WS? "," ] ;
resource_item ::= ident WS? ":" WS? expr ;

struct_lit ::= type_path WS? "{" WS? field_init_list? WS? "}" ;
type_path ::= ident { ( "." | "::" ) ident } ;
field_init_list ::= field_init { WS? "," WS? field_init } [ WS? "," ] ;
field_init ::= ident WS? ":" WS? expr
             | ident
             | ".." expr
             ;

if_expr ::= "if" WS1 expr WS? block
            { WS? "elif" WS1 expr WS? block }
            [ WS? "else" WS? block ] ;

proc_expr ::= { attr_prefix WS? } proc_modifier* "proc" WS? "(" WS? param_list? WS? ")"
              [ WS? "->" WS? type_expr ]
              WS? proc_suffix*
              WS? block ;

match_expr ::= "match" WS1 expr WS?
               "{" WS?
               { "case" WS1 pattern [ WS1 "if" WS1 expr ] WS? match_arm_body WS? }
               [ WS? "else" WS? match_arm_body ]
               WS? "}" ;

lambda_expr ::= "|" WS? param_list? WS? "|" WS? ( expr | block ) ;
unsafe_expr ::= "unsafe" WS? block ;

builtin_expr ::= sizeof_expr | alignof_expr | offsetof_expr | typeof_expr | nameof_expr ;
sizeof_expr ::= "sizeof" WS? "(" WS? ( type_expr | expr ) WS? ")" ;
alignof_expr ::= "alignof" WS? "(" WS? type_expr WS? ")" ;
offsetof_expr ::= "offsetof" WS? "(" WS? type_expr WS? "," WS? ident WS? ")" ;
typeof_expr ::= "typeof" WS? "(" WS? expr WS? ")" ;
nameof_expr ::= "nameof" WS? "(" WS? path_expr WS? ")" ;

<<< ================= Patterns ================= >>>

pattern ::= pattern_or ;
pattern_or ::= pattern_atom { WS? "|" WS? pattern_atom } ;

pattern_atom ::= "_"
               | literal
               | "mut" WS1 pattern_bind
               | "ref" WS1 pattern_bind
               | pattern_bind
               | pattern_ctor
               | pattern_struct
               | pattern_tuple
               | pattern_list
               | pattern_range
               ;

pattern_bind ::= ident ;
pattern_ctor ::= pattern_head [ "(" WS? pattern_args? WS? ")" ] ;
pattern_head ::= ident { ( "." | "::" ) ident } ;
pattern_args ::= pattern { WS? "," WS? pattern } [ WS? "," ] ;

pattern_struct ::= pattern_head WS? "{" WS? pattern_fields? WS? "}" ;
pattern_fields ::= pattern_field { WS? "," WS? pattern_field } [ WS? "," ] ;
pattern_field ::= ident [ WS? ":" WS? pattern ] | ".." ;

pattern_tuple ::= "(" WS? pattern WS? "," WS? pattern { WS? "," WS? pattern } [ WS? "," ] WS? ")" ;
pattern_list ::= "[" WS? pattern_args? WS? "]" ;
pattern_range ::= literal WS? ( ".." | "..=" ) WS? literal ;

<<< ================= Types ================= >>>

type_expr ::= type_union ;

type_union ::= type_prefix { WS? "|" WS? type_prefix } ;

type_prefix ::= type_qualifier* type_atom ;
type_qualifier ::= type_qual WS1 | addr_space WS1 ;

type_qual ::= "const" | "volatile" | "atomic" | "mut" | "owned" | "borrow" ;
addr_space ::= "user" | "kernel" | "phys" | "mmio" | "dma" ;

type_atom ::= reference_type
            | pointer_type
            | optional_type
            | fixed_array_type
            | slice_type
            | tuple_type
            | proc_type
            | dyn_type
            | impl_trait_type
            | type_primary
            ;

<<< shared and mutable references are part of the core surface grammar; lifetime,
    aliasing and region closure remain semantic checks outside the parser. >>>
reference_type ::= "&" WS? [ lifetime WS? ] [ "mut" WS1 ] type_expr ;
pointer_type ::= "*" WS? [ "const" WS1 | "mut" WS1 | "volatile" WS1 | addr_space WS1 ] type_expr ;
optional_type ::= "?" WS? type_expr ;

fixed_array_type ::= "[" WS? type_expr WS? ";" WS? expr WS? "]" ;
slice_type ::= "[" WS? type_expr 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 ] ;

type_list ::= type_param { WS? "," WS? type_param } [ WS? "," ] ;
type_param ::= ident WS? ":" WS? type_expr | type_expr ;

dyn_type ::= "dyn" WS1 trait_bound ;
impl_trait_type ::= "impl" WS1 trait_bound ;

type_primary ::= type_path [ "[" WS? type_list? WS? "]" ]
               | primitive_type
               | "Self"
               ;

lifetime ::= "'" ident ;

primitive_type ::= "void"
                 | "never"
                 | "unit"
                 | "bool"
                 | "char"
                 | "rune"
                 | "str"
                 | "string"
                 | "bytes"
                 | "cstr"
                 | "int"
                 | "i8" | "i16" | "i32" | "i64" | "i128"
                 | "u8" | "u16" | "u32" | "u64" | "u128"
                 | "usize" | "isize"
                 | "intptr" | "uintptr"
                 | "f16" | "f32" | "f64" | "f128"
                 | "c_char" | "c_int" | "c_uint" | "c_long" | "c_ulong" | "c_void"
                 | "TokenId"
                 | "NodeId"
                 | "DefId"
                 | "HirId"
                 | "MirId"
                 | "TypeId"
                 | "SymbolId"
                 | "ScopeId"
                 | "BlockId"
                 | "ValueId"
                 | "InstrId"
                 ;

<<< ================= Literals ================= >>>

literal ::= bool_lit
          | null_lit
          | int_lit
          | float_lit
          | char_lit
          | string_lit
          | list_lit
          ;

list_lit ::= "[" WS? ( list_comp | arg_list? ) WS? "]" ;
list_comp ::= expr WS1 "for" WS1 pattern WS1 "in" WS1 expr [ WS1 "if" WS1 expr ] ;

bool_lit ::= "true" | "false" ;
null_lit ::= "null" ;

int_lit ::= [ "-" ] DIGIT { DIGIT | "_" } [ suffix ]
          | [ "-" ] "0x" HEXDIGIT { HEXDIGIT | "_" } [ suffix ]
          | [ "-" ] "0b" BINDIGIT { BINDIGIT | "_" } [ suffix ]
          | [ "-" ] "0o" OCTDIGIT { OCTDIGIT | "_" } [ suffix ]
          ;

float_lit ::= [ "-" ] DIGIT { DIGIT | "_" } "." DIGIT { DIGIT | "_" } [ exponent ] [ suffix ] ;
exponent ::= ( "e" | "E" ) [ "+" | "-" ] DIGIT { DIGIT | "_" } ;

char_lit ::= "'" char_char "'" ;
char_char ::= escape_seq | ~"'" ;

string_lit ::= "\"" { string_char } "\"" | raw_string_lit ;
string_char ::= escape_seq | ~"\"" ;

escape_seq ::= "\\n"
             | "\\r"
             | "\\t"
             | "\\0"
             | "\\\""
             | "\\'"
             | "\\\\"
             | "\\x" HEXDIGIT HEXDIGIT
             | "\\u{" HEXDIGIT { HEXDIGIT } "}"
             ;

raw_string_lit ::= "\"\"\"" { raw_string_char } "\"\"\""
                 | "r\"" { raw_string_char } "\""
                 ;
raw_string_char ::= ~"\"\"\"" ;

<<< ================= Lexical ================= >>>

line_comment ::= "#" { ~NEWLINE ANY }
               | "//" { ~NEWLINE ANY }
               ;

block_comment ::= "/*" { ~"*/" ANY } "*/" ;
zone_comment ::= "<<<" { ~">>>" ANY } ">>>" ;

ident ::= ( LETTER | "_" ) { LETTER | DIGIT | "_" } ;
suffix ::= LETTER { LETTER | DIGIT } ;

WS ::= { " " | "\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 } ;

NEWLINE ::= "\n" | "\r\n" ;

LETTER ::= "a"..."z" | "A"..."Z" ;
DIGIT ::= "0"..."9" ;
BINDIGIT ::= "0" | "1" ;
OCTDIGIT ::= "0"..."7" ;
HEXDIGIT ::= DIGIT | "a"..."f" | "A"..."F" ;

EOF ::= !ANY ;