zero = _{ "0" }
nonzero = _{ '1'..'9' }
digit = _{ zero | nonzero }
lowercase = _{ 'a'..'z' }
uppercase = _{ 'A'..'Z' }
letter = _{ lowercase | uppercase }
ifs = _{ " " | "\t" }
newline = _{ "\n" | "\r\n" }
identifier = @{ letter ~ (letter | digit | "_")* }
number_greater_than_zero = @{ nonzero ~ digit* }
number_greater_or_equal_than_zero = @{ zero | number_greater_than_zero}
block_comment = _{ "/*" ~ (block_comment | !"*/" ~ ANY)* ~ "*/" }
line_comment = _{ ("//" | "#") ~(!newline ~ ANY)* }
whitespace = _{ ifs | newline }
comment = _{ block_comment | line_comment }
brk = _{ whitespace | comment }
item_end = _{ "," }
field_end = _{ "," }
stmt_end = _{ ";" }
item_decl = {
identifier ~ (brk)* ~
item_end
}
custom_union_item_decl = {
identifier ~ (brk)* ~ ":" ~ (brk)* ~
number_greater_or_equal_than_zero ~ (brk)* ~
field_end
}
field_decl = {
identifier ~ (brk)* ~ ":" ~ (brk)* ~
identifier ~ (brk)* ~
field_end
}
option_decl = {
"option" ~ (brk)+ ~ identifier ~ (brk)* ~
"(" ~ (brk)* ~
identifier ~ (brk)* ~
")" ~ (brk)* ~
stmt_end
}
union_decl = {
"union" ~ (brk)+ ~ identifier ~ (brk)* ~
"{" ~ (brk)* ~
((item_decl | custom_union_item_decl) ~ (brk)*)+ ~
"}"
}
array_decl = {
"array" ~ (brk)+ ~ identifier ~ (brk)* ~
"[" ~ (brk)* ~
identifier ~ (brk)* ~ ";" ~ (brk)* ~ number_greater_than_zero ~ (brk)* ~
"]" ~ (brk)* ~
stmt_end
}
struct_decl = {
"struct" ~ (brk)+ ~ identifier ~ (brk)* ~
"{" ~ (brk)* ~
(field_decl ~ (brk)*)+ ~
"}"
}
vector_decl = {
"vector" ~ (brk)+ ~ identifier ~ (brk)* ~
"<" ~ (brk)* ~
identifier ~ (brk)* ~
">" ~ (brk)* ~
stmt_end
}
table_decl = {
"table" ~ (brk)+ ~ identifier ~ (brk)* ~
"{" ~ (brk)* ~
(field_decl ~ (brk)*)* ~
"}"
}
decl_stmt = _{
option_decl | union_decl | array_decl
| struct_decl | vector_decl | table_decl
}
path_super = @{ "../" }
path = { path_super* ~ (identifier ~ "/")* ~ identifier }
import_stmt = { "import" ~ (brk)+ ~ path ~ (brk)* ~ stmt_end }
syntax_version = @{ digit+ }
syntax_version_stmt = { "syntax" ~ (brk)* ~ "=" ~ (brk)* ~ syntax_version ~ (brk)* ~ stmt_end}
grammar = {
SOI ~ (brk)* ~
(syntax_version_stmt)? ~ (brk)* ~
(import_stmt ~ (brk)*)* ~
decl_stmt ~
((brk)* ~ decl_stmt)* ~ (brk)* ~
EOI
}