all = S entries S / '' entries = entry S entries / entry entry = option / section option = identifier S "=" S single S ";" / identifier S "=" S compound S [";"] section = identifier S [identifier S] "{" S entries S "}" [ S ";"] values = value / value S "," S values value = single / compound compound = "{" S values S ["," S] "}" single = atom / special / single S atom / single S special ;; White space handling within a "single": ;; ;; - Unquoted white space and comments between ;; adjacent strings are deleted. ;; ;; "foo" "bar" -> same as "foobar" ;; ;; - Unquoted white space and comments other than ;; between strings are normalized to a single space. ;; ;; foo bar -> same as foo bar ;; "foo" bar -> same as foo bar ;; foo "bar" -> same as foo bar ;; ;; - White space and comments that are part of ;; quoted strings are left unchanged. ;; special = "!" / "$" / "%" / "&" / "'" / "(" / ")" / "*" / "+" / "-" / "." / "/" / ":" / "<" / ">" / "?" / "@" / "[" / "]" / "\\" / "^" / "`" / "|" / "~" / %x80-FF ;; any visible non-whitespace-or-comment char that's neither ;; [a-z0-9S] nor one of '{' '}' ',' ';' '=' '"' atom = identifier / string identifier = (alpha / "_") *(alpha / digit / "_") string = <"> *cchar <"> cchar = %x00-09 / %x11-21 / %x23-5B / %x5D-FF ;; any 8-bit char except " \ or new-line / "\" escape-sequence escape-sequence = "a" / "b" / "f" / "n" / "r" / "t" / "v" / smalloct [ oct [ oct ]] / "x" hex *(hex) / %x75 hex hex hex hex ;; %x75 -- lower-case u / %x31 "0000" hex hex hex hex ;; %x31 -- upper-case U / %x00-09 / %x11-2F / %x3A-54 / %x56-74 / %x76-77 / %x79-FF ;; the \ is not part of the string value. alpha = "a" / "b" / "c" / "d" / "e" / "f" / "g" / "h" / "i" / "j" / "k" / "l" / "m" / "n" / "o" / "p" / "q" / "r" / "s" / "t" / "u" / "v" / "w" / "x" / "y" / "z" smalloct = "0" / "1" / "2" / "3" oct = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" digit = oct / "8" / "9" hex = digit / "a" / "b" / "c" / "d" / "e" / "f" S = S " " / S %x0A / S %x0D / S %x09 / "" / "#" comment %x0A comment = comment comchar / "" comchar = %x00-09 / %x11-FF