(* Grammatical EBNF *) Ruleset = (COMMENT? Rule)* EOI ; Rule = ident '=' Either? ';' ; Either = Follow ('|' Follow)* ; Follow = (Any | Many | Maybe | Not)+ ; Any = Not '*' ; Many = Not '+' ; Maybe = Not '?' ; Not = '!'? Prime ; Prime = Group | chr | str | ident ; Group = '(' Either ')' ; ident = XID_START XID_CONTINUE* ; str = '"' (!'"' ANY)* '"' ; chr = "'" (!"'" ANY)* "'" ; WHITESPACE = WHITE_SPACE ; COMMENT = "(*" (COMMENT | !"*)" ANY)* "*)" ;