// Geno PEG grammar
_schema = _{ SOI ~ meta_data ~ declaration* ~ EOI }
declaration = _{ enum_decl | struct_decl | include_stmt }
// Include statements
include_stmt = { "include" ~ string_literal }
// Metadata
meta_data = { "#[" ~ meta_data_list+ ~ "]" }
meta_data_list = { meta_data_entry ~ ("," ~ meta_data_entry)* ~ ","? }
meta_data_entry = { identifier ~ "=" ~ (string_literal | integer_literal) }
// Enum declaration
enum_decl = { "enum" ~ identifier ~ (":" ~ integer_type)? ~ "{" ~ enum_variant_list ~ "}" }
enum_variant_list = { enum_variant ~ ("," ~ enum_variant)* ~ ","? }
enum_variant = { identifier ~ "=" ~ integer_literal }
// Struct declaration
struct_decl = { "struct" ~ identifier ~ "{" ~ struct_field_list ~"}" }
struct_field_list = { struct_field ~ ("," ~ struct_field)* ~ ","? }
struct_field = { identifier ~ ":" ~ field_type }
// Field types
field_type = { (array_type | map_type | builtin_type | identifier) ~ nullable? }
array_type = { "[" ~ field_type ~ (";" ~ integer_literal)? ~ "]" }
map_type = { "{" ~ builtin_type ~ ":" ~ field_type ~ "}" }
nullable = { "?" }
// Built-in types
builtin_type = { integer_type | float_type | string_type | bool_type }
string_type = { "string" }
bool_type = { "bool" }
integer_type = { "i8" | "u8" | "i16" | "u16" | "i32" | "u32" | "i64" | "u64" }
float_type = { "f32" | "f64" }
// Literals
integer_literal = @{ ("0b" ~ ASCII_BIN_DIGIT+) | ("0x" ~ ASCII_HEX_DIGIT+) | (("-" | "+")? ~ ASCII_DIGIT+) }
string_literal = @{ "\"" ~ ("\\\"" | !("\"") ~ ANY)* ~ "\"" }
// Identifier
identifier = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_" | "-")* }
// Whitespace and comments (silently consumed)
WHITESPACE = _{ " " | "\t" | NEWLINE }
COMMENT = _{ "//" ~ (!NEWLINE ~ ANY)* }