Root = { SOI ~ NEWLINE* ~ Preamble ~ WHITE_SPACE* ~ Section* ~ WHITE_SPACE* ~ EOI }
Preamble = { "RULES FOR " ~ Name ~ " PRODUCE " ~ MediaType ~ NEWLINE }
Section = { Header ~ NEWLINE+ ~ (Rule | NEWLINE+)* }
Header =_{ SECTION ~ " RULES:" }
Rule = { Path ~ NEWLINE ~
INDENT ~ (Command | Settings) ~ NEWLINE ~
(PEEK_ALL ~ Command ~ NEWLINE )* ~
UNINDENT
}
Path = { !(" " | Header) ~ ANY_LETTER+ }
Command = { Op ~ (" "+ ~ Args)? }
Settings = { "IS " ~ ANY_LETTER+ }
Name = { ASCII_ALPHANUMERIC+ }
Op = { KEYWORD }
Args =_{ Arg ~ (" "+ ~ Arg)* }
Arg =_{ "\"" ~ Str ~ "\"" | ArtifactDest | ArtifactPath | Prop | Int | StackRef }
ArtifactDest=_{ "TO " ~ (MediaType | "\"" ~ File ~ "\"") }
ArtifactPath=_{ "AS " ~ "\"" ~ URIPath ~ "\"" }
Prop =_{ "PROP " ~ PropRef }
MediaType =@{ ASCII_ALPHA+ ~ "/" ~ ASCII_ALPHA+ ~ (";" ~ ASCII_ALPHA+ ~ "=" ~ ASCII_ALPHANUMERIC+)? }
File =@{ Str }
URIPath = { Str }
PropRef =@{ StackRef }
Str = { (!(NEWLINE | "\"") ~ ("\\\"" | ANY_LETTER))* }
Int = { ASCII_DIGIT+ }
StackRef = { (!(NEWLINE | WHITE_SPACE | "\\") ~ ANY_LETTER )+ }
ANY_LETTER =_{ LETTER | NUMBER | MARK | PUNCTUATION | SYMBOL | SEPARATOR }
KEYWORD =_{ "DEC" | "DRAIN" | "EXEC" | "INC" | "LOAD" | "NOOP" | "PUSH" | "POP" | "SET" | "SWAP" | "WRITEALL" | "WRITE" | "YIELD" }
SECTION = { "PREPROCESS" | "COMPILE" }
INDENT =_{ PUSH(" ") }
UNINDENT =_{ DROP }
COMMENT =_{ WHITE_SPACE* ~ "/*" ~ (!"*/" ~ ANY)* ~ "*/" }