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)* }