program = _{ SOI ~ terms ~ EOI } terms = _{ term* } term = _{ value } value = _{ lambda | list | ctx | ptr | name | command | atom | stack | string | literal | float | integer } integer = @{ ("+" | "-")? ~ int } float = @{ ("+" | "-")? ~ int ~ "." ~ ( digits ~ exp? | exp)? } string = @{ "\"" ~ inner ~ "\"" } literal = @{ "'" ~ (!"'" ~ literal_element )* ~ "'" } atom = @{ ":" ~ aelement+ ~ WHITESPACE+ } stack = @{ "@" ~ LETTER+ ~ WHITESPACE+ } name = @{ !"`" ~ element ~ nelement* ~ WHITESPACE+ } ptr = @{ "`" ~ element ~ nelement* ~ WHITESPACE+ } command = @{ cmd+ ~ WHITESPACE+ } lambda = { "{" ~ term+ ~ "}" } list = { "[" ~ term+ ~ "]" } ctx = { "(" ~ term+ ~ ")" } element = @{ ( LETTER | SYMBOL | "." | "," | "=" | ">" | "<" | "-" | "+" | "^" | "?" | "!" | "/" | "*" | "|" | "&" | "#" | "%" | "_" ) } nelement = @{ ( element | ASCII_DIGIT ) } aelement= @{ (ASCII_ALPHANUMERIC | LETTER) } literal_element= @{ ANY | "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t") | "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4}) } cmd = @{ ( ":" | ";" ) } inner = @{ (!("\"" | "\\" | "\u{0000}" | "\u{001F}") ~ ANY)* ~ (escape ~ inner)? } escape = @{ "\\" ~ ("b" | "t" | "n" | "f" | "r" | "\"" | "\\" | unicode | NEWLINE)? } unicode = @{ "u" ~ ASCII_HEX_DIGIT{4} | "U" ~ ASCII_HEX_DIGIT{8} } int = @{ "0" | (ASCII_NONZERO_DIGIT ~ digits?) } digits = @{ (ASCII_DIGIT | ("_" ~ ASCII_DIGIT))+ } exp = @{ ("E" | "e") ~ ("+" | "-")? ~ int } WHITESPACE = _{ " " | "\t" | "\r" | "\n" } COMMENT = _{ "//" ~ (!"\n" ~ ANY)* }