-s ::= ws grammar ws => "gram"
-ws !::= w**
-grammar ::= r +/ ws => "grammar"
-r ::= word ^"::=" alternatives /ws
- | word ^"!::=" alternatives /ws
+// use 'a'-'z' or 'a-z' instead of [a-z]?
+// EOF token?
+// #include (with renaming?)
-alternatives ::= equiAlt +/ (ws ">" ws)
-equiAlt ::= conjuncts +/ (ws "|" ws)
+s = ws! Grammar ws!
-sequence ::= es
- > es ws ^"/" e
-es ::= e */ (w**)
+Grammar = Declaration +/ ws
-ss ::= es | es ^"/" e /ws
+Declaration = NonTerminal
+ | ^"#import" ws! FileName (ws! "as" ws! Word)?
-conjuncts ::= rewrite
- | rewrite ^"&" e*/ws /ws
- | rewrite ^"&~" e*/ws /ws
+FileName = FileNameChar+ -> [\r\n ]
+FileNameChar = Space:: "\\ "
+ | ~[\r\n ]
-rewrite ::= sequence /ws => "rewrite"
- | sequence ^"=>" word /ws
- | sequence ^"=>" quoted /ws
+NonTerminal = Word "=" RHS /ws
+ | Word "*" ws! ^"=" ws! RHS
+ | Word "*/" Word ws! ^"=" ws! RHS
+
+RHS = (Sequence +/ (ws! "|" ws!)) +/ (ws! ">" ws!)
-ec ::= [~\-\]\\\~]
- | escaped
+Elements = e*/ws
-range ::= ec => "range"
- | ec ^"-" ec
+PreSequence = Elements
+ | (Quoted|Word) ^"::" PreSequence /ws
+ > PreSequence ^"/" e /ws
+ | PreSequence ^"->" e /ws
-e ::= word => "nonTerminal"
- | [(][)] => "epsilon"
- | ^"{" alternatives "}" /ws
- | ^"[" (range*) "]"
- | ^"[~" (range*) "]"
- | ^"^" quoted /ws
- | e ^"~/~" /ws
- | ^"!" e /ws
+Sequence = psx:: PreSequence
+ | Sequence ^"&" Elements /ws
+ | Sequence ^"&~" Elements /ws
- | ^"`" e /ws
- | e ^"#" /ws
+ec = ~[\-\]\\]
+ | escaped
- | (e ws ^"**" > e ws ^"*")
- | e ^"*/" e /ws
- | (e ws ^"++" > e ws ^"+")
- | e ^"+/" e /ws
- | e ^"?" /ws
+Range = ec
+ | ec "-" ec
- | quoted => "literal"
+e = (Quoted|Word) ^":" e
+ > NonTerminalReference
+ | Literal
+ | ^"()"
+ | ^"{" PreSequence "}" /ws
+ | ^"[" Range* "]"
+ | e ^"++" /ws -> ~[/]
+ | e ^"+" /ws -> ~[+]
+ | e ^"++/" e /ws
+ | e ^"+/" e /ws
+ | e ^"**" /ws -> ~[/]
+ | e ^"*" /ws -> ~[*]
+ | e ^"**/" e /ws
+ | e ^"*/" e /ws
+ | e ^"!"
+ | e ^"?" /ws
+ | ^"^" Quoted
+ > ^"(" RHS ")" /ws
+ | ^"~" e
- | "(" word ^")" /ws
- > ^"(" alternatives ")" /ws
-
-w !::= " "
- | "//" ([~\n]*) "\n"
- | "\n"
- | "\r"
-an ::= [a-zA-Z0-9_]
-word ::= an++
-quoted ::= "\"" (([~\"\\] | escaped)+) "\""
- | "\"\"" => ""
-escaped ::= "\\n" => "\n"
- | "\\r" => "\r"
- | "\\" [~nr]
+NonTerminalReference = Word
+Literal = Quoted
+Word = [.a-zA-Z0-9_]++
+Quoted = "\"" ((~[\"\\] | escaped)+) "\""
+ | EmptyString
+ EmptyString = "\"\""
+escaped = "\n":: "\\n"
+ | "\r":: "\\r"
+ | "\\" ~[nr]
+w = " " | "\n" | "\r"
+ws = w**
+ | w** "//" (~[\n])*! "\n" ws!
+wp = w++