WHITESPACE = _{ WHITE_SPACE } COMMENT = _{ "//" ~ (!NEWLINE ~ ANY)* ~ (NEWLINE | EOI) } ws = _{ WHITESPACE | COMMENT | EOI } lit_pos_nonzero_int = @{ ('1'..'9') ~ ('0'..'9')* } lit_pos_int = @{ "0" | lit_pos_nonzero_int } lit_int = @{ "0" | ("-"? ~ lit_pos_nonzero_int) } lit_string_char = @{ "\\\"" | (!("\"" | NEWLINE) ~ ANY) } lit_string = @{ "\"" ~ lit_string_char* ~ "\"" } lit_uuid = @{ ASCII_HEX_DIGIT{8} ~ "-" ~ ASCII_HEX_DIGIT{4} ~ "-" ~ ASCII_HEX_DIGIT{4} ~ "-" ~ ASCII_HEX_DIGIT{4} ~ "-" ~ ASCII_HEX_DIGIT{12} } tok_term = @{ ";" } tok_eq = @{ "=" } tok_par_open = @{ "(" } tok_par_close = @{ ")" } tok_ang_open = @{ "<" } tok_ang_close = @{ ">" } tok_arrow = @{ "->" } tok_scope = @{ "::" } tok_hash = @{ "#" } tok_squ_open = @{ "[" } tok_squ_close = @{ "]" } tok_comma = @{ "," } tok_cur_open = @{ "{" } tok_cur_close = @{ "}" } tok_at = @{ "@" } kw_import = @{ "import" ~ &ws } kw_struct = @{ "struct" ~ &ws } kw_enum = @{ "enum" ~ &ws } kw_service = @{ "service" ~ &ws } kw_fn = @{ "fn" ~ &ws } kw_event = @{ "event" ~ &ws } kw_const = @{ "const" ~ &ws } kw_u8 = @{ "u8" } kw_i8 = @{ "i8" } kw_u16 = @{ "u16" } kw_i16 = @{ "i16" } kw_u32 = @{ "u32" } kw_i32 = @{ "i32" } kw_u64 = @{ "u64" } kw_i64 = @{ "i64" } kw_string = @{ "string" } kw_uuid = @{ "uuid" } kw_object_id = @{ "object_id" } kw_service_id = @{ "service_id" } kw_bool = @{ "bool" } kw_f32 = @{ "f32" } kw_f64 = @{ "f64" } kw_value = @{ "value" } kw_box = @{ "box" } kw_vec = @{ "vec" } kw_bytes = @{ "bytes" } kw_map = @{ "map" } kw_set = @{ "set" } kw_required = @{ "required" } kw_option = @{ "option" } kw_version = @{ "version" } kw_args = @{ "args" } kw_ok = @{ "ok" } kw_err = @{ "err" } kw_sender = @{ "sender" } kw_receiver = @{ "receiver" } kw_lifetime = @{ "lifetime" } kw_unit = @{ "unit" } kw_result = @{ "result" } ident = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* } schema_name = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* } external_ref = { schema_name ~ tok_scope ~ ident } named_ref = { external_ref | ident } option_type = { kw_option ~ tok_ang_open ~ type_name ~ tok_ang_close } box_type = { kw_box ~ tok_ang_open ~ type_name ~ tok_ang_close } vec_type = { kw_vec ~ tok_ang_open ~ type_name ~ tok_ang_close } map_type = { kw_map ~ tok_ang_open ~ key_type_name ~ tok_arrow ~ type_name ~ tok_ang_close } set_type = { kw_set ~ tok_ang_open ~ key_type_name ~ tok_ang_close } sender_type = { kw_sender ~ tok_ang_open ~ type_name ~ tok_ang_close } receiver_type = { kw_receiver ~ tok_ang_open ~ type_name ~ tok_ang_close } result_type = { kw_result ~ tok_ang_open ~ type_name ~ tok_comma ~ type_name ~ tok_ang_close } array_len = { lit_pos_int | named_ref } array_type = { tok_squ_open ~ type_name ~ tok_term ~ array_len ~ tok_squ_close } key_type_name = { kw_u8 | kw_i8 | kw_u16 | kw_i16 | kw_u32 | kw_i32 | kw_u64 | kw_i64 | kw_string | kw_uuid } type_name = { kw_bool | kw_u8 | kw_i8 | kw_u16 | kw_i16 | kw_u32 | kw_i32 | kw_u64 | kw_i64 | kw_f32 | kw_f64 | kw_string | kw_uuid | kw_object_id | kw_service_id | kw_value | option_type | box_type | vec_type | kw_bytes | map_type | set_type | sender_type | receiver_type | kw_lifetime | kw_unit | result_type | array_type | named_ref } type_name_or_inline = { (type_name ~ tok_term) | struct_inline | enum_inline } file = _{ SOI ~ import_stmt* ~ def* ~ EOI } attribute = { tok_hash ~ tok_squ_open ~ ident ~ (tok_par_open ~ ident ~ (tok_comma ~ ident)* ~ tok_comma? ~ tok_par_close)? ~ tok_squ_close } import_stmt = { kw_import ~ schema_name ~ tok_term } def = { struct_def | enum_def | service_def | const_def } struct_def = { attribute* ~ kw_struct ~ ident ~ tok_cur_open ~ struct_field* ~ tok_cur_close } struct_inline = { kw_struct ~ tok_cur_open ~ struct_field* ~ tok_cur_close } struct_field = { kw_required? ~ ident ~ tok_at ~ lit_pos_int ~ tok_eq ~ type_name ~ tok_term } enum_def = { attribute* ~ kw_enum ~ ident ~ tok_cur_open ~ enum_variant* ~ tok_cur_close } enum_inline = { kw_enum ~ tok_cur_open ~ enum_variant* ~ tok_cur_close } enum_variant = { ident ~ tok_at ~ lit_pos_int ~ (tok_eq ~ type_name)? ~ tok_term } service_def = { kw_service ~ ident ~ tok_cur_open ~ service_uuid ~ service_version ~ service_item* ~ tok_cur_close } service_uuid = { kw_uuid ~ tok_eq ~ lit_uuid ~ tok_term } service_version = { kw_version ~ tok_eq ~ lit_pos_int ~ tok_term } service_item = { fn_def | event_def } fn_def = { kw_fn ~ ident ~ tok_at ~ lit_pos_int ~ ((tok_cur_open ~ fn_body ~ tok_cur_close) | tok_term) } fn_body = _{ fn_args? ~ fn_ok? ~ fn_err? } fn_args = { kw_args ~ tok_eq ~ type_name_or_inline } fn_ok = { kw_ok ~ tok_eq ~ type_name_or_inline } fn_err = { kw_err ~ tok_eq ~ type_name_or_inline } event_def = { kw_event ~ ident ~ tok_at ~ lit_pos_int ~ ((tok_eq ~ type_name_or_inline) | tok_term) } const_def = { kw_const ~ ident ~ tok_eq ~ const_value ~ tok_term } const_value = { const_u8 | const_i8 | const_u16 | const_i16 | const_u32 | const_i32 | const_u64 | const_i64 | const_string | const_uuid } const_u8 = { kw_u8 ~ tok_par_open ~ lit_int ~ tok_par_close } const_i8 = { kw_i8 ~ tok_par_open ~ lit_int ~ tok_par_close } const_u16 = { kw_u16 ~ tok_par_open ~ lit_int ~ tok_par_close } const_i16 = { kw_i16 ~ tok_par_open ~ lit_int ~ tok_par_close } const_u32 = { kw_u32 ~ tok_par_open ~ lit_int ~ tok_par_close } const_i32 = { kw_i32 ~ tok_par_open ~ lit_int ~ tok_par_close } const_u64 = { kw_u64 ~ tok_par_open ~ lit_int ~ tok_par_close } const_i64 = { kw_i64 ~ tok_par_open ~ lit_int ~ tok_par_close } const_string = { kw_string ~ tok_par_open ~ lit_string ~ tok_par_close } const_uuid = { kw_uuid ~ tok_par_open ~ lit_uuid ~ tok_par_close }