pred-recdec 0.2.1

Predicated Recursive Descent Parsing with BNF and impure hooks
Documentation
# Predicated Recursive Descent grammar for JSON
# Simpler, slightly slower version
# Passes all of the parsing tests in https://github.com/nst/JSONTestSuite
json ::= element $become EOF
EOF ::= @eof

element ::=
   @peek(0, "{") object | @peek(0, "[") array
   # A``r regex strings match any token that starts with the contained regex
   | @peekr(0, A`"`r) string
   | @auto "true" | @auto "false" | @auto "null"
   | number

object ::= @peek(1, "}") "{" "}" | "{" members "}"
members ::= member $become memberlist
memberlist ::= @auto "," member $become memberlist | #empty
member ::= string ":" element

array ::= @peek(1, "]") "[" "]" | "[" elements "]"
# Lookahead/predicates are necessary for any non-final alternation. Alternations are attempted in order, and never backtracked/memoized.
# Example: this would never attempt to match the "elements" production: array ::= "[" "]" | "[" elements "]"

elements ::= element $become elementlist
elementlist ::= @auto "," element $become elementlist | #empty
# NOTE: #empty is just a comment. It's not a magical way of writing epsilons.

# r``r regex strings both perform a match test at parse time (cached) and Also register themselves with the tokenizer.
# R``r do the same, but WITHOUT registering themselves with the tokenizer. A``r also do not register with the tokenizer.
string ::= r`"(?:[ !#-\[\]-\u{10ffff}]|\\["\\\/bfnrt]|\\u[a-fA-F0-9]{4})*"`r
number ::= r`[-]?(?:[1-9][0-9]+|[0-9])(?:\.[0-9]+)?(?:[eE][-+]?[0-9]+)?`r