grammar = _{ SOI ~ (rules | rule_preface ~ NEWLINE+ ~ rules ~ (weight_preface ~ NEWLINE+ ~ weights)? ) ~ EOI }
rule_preface = _{ (NEWLINE | " ")* ~ "RULES:" }
weight_preface = _{ (NEWLINE | " ")* ~ "WEIGHTS:" }
rules = { (NEWLINE | " ")* ~ rule ~ ((NEWLINE | " ")* ~ rule)* ~ (NEWLINE | " ")* }
rule = { " "* ~lhs ~ " "* ~ "=" ~ " "* ~ rhs }
lhs = { id }
rhs = { node+ }
node = _{non_terminal | var_ref | optional | choice | sequence | text}
optional = { "?:[" ~ node+ ~ "]" }
choice = { "[" ~ choice_arm ~ "|" ~ (NEWLINE ~ " "*)? ~ choice_arm ~ ("|" ~ (NEWLINE ~ " "*)? ~ choice_arm)* ~ "]" }
choice_arm = { node+ }
sequence = { "[" ~ node+ ~ "]" }
non_terminal = ${ "<" ~ id ~ ">" }
var_ref = ${ "#" ~ id ~ ("|" ~ id)? ~ "#" }
weights = { (NEWLINE | " ")* ~ weight ~ ((NEWLINE | " ")* ~ weight)* ~ (NEWLINE | " ")* }
weight = { " "* ~ lhs ~ " "* ~ "=" ~ " "* ~ float }
float = { ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? }
id = { XID_START ~ (XID_CONTINUE)* }
text = ${ (nonspecial)+ }
nonspecial = _{ !("<" | "#" | "[" | "]" | "|" | NEWLINE) ~ ANY }