file = { SOI ~ ( generatefile_stmt | generate_stmt | filecontents | other)* ~ EOI } other = _{ (!NEWLINE ~ ANY) } generatefile_stmt = _{ "\\generateFile" ~ LPAREN ~ filename ~ RPAREN } generate_stmt = _{ "\\generate" ~ LPAREN ~ (file_stmt | cmd )+ ~ RPAREN } file_stmt = _{ "\\file" ~ LPAREN ~ filename ~ RPAREN ~ LPAREN ~ (from | cmd) + ~RPAREN } filecontents = _{ "\\begin" ~ LPAREN ~ filecontents_lit ~ RPAREN ~ LPAREN ~ filename ~ RPAREN } filecontents_lit = _{ "filecontents*" | "filecontents" } filename = { (!RPAREN ~ ANY)* } from = _{ "\\from" ~ LPAREN ~ anyx ~ RPAREN ~ LPAREN ~ anyx ~ RPAREN } cmd = _{ "\\" ~ ident ~ (LPAREN ~ anyx ~ RPAREN)* } ident_char = _{ 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" } ident = _{ ('a'..'z' | 'A'..'Z') ~ ident_char* | "_" ~ ident_char+ } LPAREN = _{ "{" } RPAREN = _{ "}" } anyx = _{ (!RPAREN ~ ANY)* } WHITESPACE = _{ " " | "\t" | NEWLINE } COMMENT = _{ "%" ~ (!NEWLINE ~ ANY)* }