throne 0.5.0

Scripting language for game prototyping and story logic
Documentation
WHITESPACE = _{ " " }
COMMENT = _{ ("//" ~ (!NEWLINE ~ ANY)*) | ("/*" ~ (!"*/" ~ ANY)* ~ "*/") }
atom = @{ (ASCII_ALPHANUMERIC | "_" | "-")+ ~ "'"* }
atom_var = @{ ASCII_ALPHA_UPPER ~ (ASCII_ALPHA_UPPER | ASCII_DIGIT | "_" | "-")* ~ "'"* }
string = { "\"" ~ (!"\"" ~ ANY)* ~ "\"" }
wildcard = @{ "_" ~ atom? }
qui = { "qui" }

// list <= and >= first, to give precendence over < and >
prefix = { !(wildcard | string | atom_var | atom) ~ ("+" | "-" | "%" | "<=" | ">=" | "<" | ">" | "#" | "==") }

phrase_compound = { prefix? ~ ((wildcard | string | atom_var | atom)+ | "(" ~ phrase_compound+ ~ ")") }
phrase = !{ phrase_compound+ }

stage_phrase = ${ "#" ~ phrase }
copy_phrase = ${ "$" ~ phrase }
side_phrase = ${ "^" ~ phrase }
negate_phrase = ${ "!" ~ phrase }
nonconsuming_phrase = ${ "?" ~ phrase }
backwards_phrase = ${ "<<" ~ phrase }

compiler_block = _{ "[" ~ (compiler_enable_unused_warnings | compiler_disable_unused_warnings) ~ "]" }
compiler_enable_unused_warnings = { "enable-unused-warnings" }
compiler_disable_unused_warnings = { "disable-unused-warnings" }

state_phrase = { stage_phrase | phrase }
state = { state_phrase ~ (NEWLINE? ~ "." ~ NEWLINE? ~ state_phrase)* }

input_phrase = { qui | stage_phrase | copy_phrase | side_phrase | negate_phrase | backwards_phrase | nonconsuming_phrase | phrase }
inputs = { input_phrase ~ (NEWLINE? ~ "." ~ NEWLINE? ~ input_phrase)* }
output_phrase = { qui | stage_phrase | side_phrase | phrase }
outputs = { output_phrase ~ (NEWLINE? ~ "." ~ NEWLINE? ~ output_phrase)* }
rule = { inputs ~ NEWLINE? ~ "=" ~ NEWLINE? ~ outputs }

backwards_def_phrase = { stage_phrase | side_phrase | negate_phrase | nonconsuming_phrase | phrase }
backwards_def = { backwards_phrase ~ (NEWLINE? ~ "." ~ NEWLINE? ~ backwards_def_phrase)* }

prefix_block = _{ "{" ~ NEWLINE* ~ rule ~ (NEWLINE+ ~ rule)* ~ NEWLINE* ~ "}" }
prefixed = { inputs ~ ":" ~ prefix_block }

file = {
  SOI ~
  (NEWLINE* ~ (prefixed | rule | backwards_def | state | compiler_block))* ~
  NEWLINE* ~ EOI
}