WHITESPACE = _{ " " | "\t" }
COMMENT = _{ "#" ~ (!newline ~ ANY)* }
config = _{ SOI ~ (directive+ | newline)* ~ EOI }
directive = _{ ((plugin_spec | source | other) ~ (newline | EOI)) }
newline = _{ "\r" | "\n" }
plugin_spec = { set_option ~ "-g" ~ "@plugin" ~ quoted_string }
source = { source_file ~ source_file_flags ~ quoted_string }
other = @{ ("\\" ~ newline | !newline ~ ANY)+ }
set_option = @{ "set" ~ ("-option")? }
source_file = @{ "source" ~ ("-file")? }
source_file_flags = @{ ("-" ~ (ASCII_ALPHANUMERIC+) ~ WHITESPACE)* }
//
// --- Quoted String ----------------------------------------------------------
//
quoted_string = { (single_quoted_string | double_quoted_string) }
double_quoted_string = ${ PUSH("\"") ~ quoted_inner ~ POP }
single_quoted_string = ${ PUSH("'") ~ quoted_inner ~ POP }
// This allows to escape double quote characters when inside a double-quoted
// string but does not allow escaping single quote characters inside a
// single-quoted string.
// To also allow escaping single quotes inside single-quoted strings, replace
// `("\\\"")` with `("\\" ~ PEEK)`.
quoted_inner = { (("\\\"") | (!PEEK ~ ANY))* }