delbin 0.1.0

Descriptive Language for Binary Object
Documentation
// ============================================================
// Delbin Grammar - Descriptive Language for Binary Object
// ============================================================

// Whitespace and comments
WHITESPACE = _{ " " | "\t" | "\r" | "\n" }
COMMENT    = _{ "//" ~ (!"\n" ~ ANY)* }

// ============================================================
// Top-level structure
// ============================================================
file = { SOI ~ directive* ~ struct_def ~ EOI }

// ============================================================
// Directives
// ============================================================
directive       = { "@" ~ directive_name ~ "=" ~ directive_value ~ ";" }
directive_name  = { "endian" }
directive_value = { "little" | "big" }

// ============================================================
// Struct definition
// ============================================================
struct_def  = { "struct" ~ ident ~ struct_attr* ~ "{" ~ field_def* ~ "}" }
struct_attr = { "@" ~ ( "packed" | align_attr ) }
align_attr  = { "align" ~ "(" ~ dec_number ~ ")" }

// ============================================================
// Field definition
// ============================================================
field_def = { ident ~ ":" ~ type_spec ~ ( "=" ~ (array_literal | expr) )? ~ ";" }

// ============================================================
// Types
// ============================================================
type_spec    = { array_type | scalar_type }
scalar_type  = @{ ( "u" | "i" ) ~ ( "8" | "16" | "32" | "64" ) }
array_type   = { "[" ~ scalar_type ~ ";" ~ expr ~ "]" }

// ============================================================
// Expressions
// ============================================================
expr         = { or_expr }
or_expr      = { and_expr ~ ( "|" ~ and_expr )* }
and_expr     = { shift_expr ~ ( "&" ~ shift_expr )* }
shift_expr   = { add_expr ~ ( shift_op ~ add_expr )* }
add_expr     = { unary_expr ~ ( add_op ~ unary_expr )* }
unary_expr   = { unary_op? ~ primary_expr }

shift_op     = { "<<" | ">>" }
add_op       = { "+" | "-" }
unary_op     = { "~" }

primary_expr = {
    builtin_call
  | env_var
  | hex_number
  | bin_number
  | dec_number
  | string
  | ident
  | "(" ~ expr ~ ")"
}

// ============================================================
// Built-in function call
// ============================================================
builtin_call = { "@" ~ builtin_name ~ "(" ~ arg_list? ~ ")" }
builtin_name = @{ "bytes" | "sizeof" | "offsetof" | "crc32" | "crc" | "sha256" }
arg_list     = { arg ~ ( "," ~ arg )* }

arg = {
    range_expr    // @self or @self[..xxx] takes priority
  | expr          // General expression (string, number, identifier, etc.)
}

// ============================================================
// Range expression
// ============================================================
range_expr   = { "@self" ~ ( "[" ~ range_spec ~ "]" )? }
range_spec   = { range_start? ~ ".." ~ range_end? }
range_start  = { ident | hex_number | bin_number | dec_number }
range_end    = { ident }

// ============================================================
// Array literal
// ============================================================
array_literal = { "[" ~ array_content ~ "]" }
array_content = { repeat_form | list_form }
repeat_form   = { array_elem ~ ";" ~ (dec_number | infer_marker) }
list_form     = { array_elem ~ ("," ~ array_elem)* }
array_elem    = { env_var | hex_number | bin_number | dec_number }
infer_marker  = { "_" }

// ============================================================
// Literals
// ============================================================
hex_number   = @{ "0x" ~ ASCII_HEX_DIGIT+ }
bin_number   = @{ "0b" ~ ( "0" | "1" )+ }
dec_number   = @{ ASCII_DIGIT+ }
string       = ${ "\"" ~ string_inner ~ "\"" }
string_inner = @{ ( !( "\"" | "\\" ) ~ ANY | escape_seq )* }
escape_seq   = @{ "\\" ~ ( "n" | "r" | "t" | "\\" | "\"" | "0" | ( "x" ~ ASCII_HEX_DIGIT{2} ) ) }

// ============================================================
// Environment variables
// ============================================================
env_var = { "${" ~ ident ~ "}" }

// ============================================================
// Identifiers
// ============================================================
ident  = @{ ( ASCII_ALPHA | "_" ) ~ ( ASCII_ALPHANUMERIC | "_" )* }