; The JAXN grammar (https://github.com/stand-art/jaxn/)

; Based on the JSON grammar, see RFC 8259.
; See RFC 5234 for interpretation and core rules.

comment = c-line / c-block

c-line = c-begin-line *( c-char )

c-begin-line = %x23 / %x2F.2F ; # or //

c-char = %x09 / %x20-7E / %x80-10FFFF
                              ; Any HTAB or printable character

c-block = c-begin-block
          *( c-no-star / ( 1*c-star c-no-star-or-slash ) )
          c-end-block

c-begin-block = c-slash c-star
c-end-block = 1*c-star c-slash

c-slash = %x2F                ; /
c-star = %x2A                 ; *

c-no-star = %x09 / %x0A / %x0D /
            %x20-29 / %x2B-7E / %x80-10FFFF

c-no-star-or-slash = %x09 / %x0A / %x0D /
                     %x20-29 / %x2B-2E / %x30-7E / %x80-10FFFF

ws = *( %x20 /                ; Space
        %x09 /                ; Horizontal tab
        %x0A /                ; Line feed or New line
        %x0D /                ; Carriage return
        comment )             ; Comment

begin-array     = ws %x5B ws  ; [ left square bracket
begin-object    = ws %x7B ws  ; { left curly bracket
end-array       = ws %x5D ws  ; ] right square bracket
end-object      = ws %x7D ws  ; } right curly bracket
name-separator  = ws %x3A ws  ; : colon
value-separator = ws %x2C ws  ; , comma
value-concat    = ws %x2B ws  ; + plus

value-sep-opt = [ value-separator ]

null  = %x6E.75.6C.6C         ; null
true  = %x74.72.75.65         ; true
false = %x66.61.6C.73.65      ; false

number = [ plus / minus ] ( nan / inf / hex / dec )

nan = %x4E.61.4E              ; NaN

inf = %x49.6E.66.69.6E.69.74.79
                              ; Infinity

hex = zero x 1*HEXDIG         ; 0xXXX...

dec = ( int [ frac0 ] / frac1 ) [ exp ]

decimal-point = %x2E          ; .

digit1-9 = %x31-39            ; 1-9

e = %x65 / %x45               ; e E
x = %x78 / %x58               ; x X

exp = e [ plus / minus ] 1*DIGIT

frac0 = decimal-point *DIGIT
frac1 = decimal-point 1*DIGIT

int = zero / ( digit1-9 *DIGIT )

plus = %x2B                   ; +
minus = %x2D                  ; -
zero = %x30                   ; 0

string = string-part *( value-concat string-part )

string-part = m-d-string / m-s-string / d-string / s-string

m-d-string = 3d-quote *( m-d-char ) 3d-quote
m-s-string = 3s-quote *( m-s-char ) 3s-quote

m-d-char = *2d-quote ( %x09 / %x0A / %x0D / %x20-21 / %x23-7E / %x80-10FFFF )
m-s-char = *2s-quote ( %x09 / %x0A / %x0D / %x20-26 / %x28-7E / %x80-10FFFF )

d-string = d-quote *( s-char / s-quote ) d-quote
s-string = s-quote *( s-char / d-quote ) s-quote

s-char = unescaped /
         escape (
             %x22 /           ; "    double quote    U+0022
             %x27 /           ; '    single quote    U+0027
             %x5C /           ; \    reverse solidus U+005C
             %x2F /           ; /    solidus         U+002F
             %x30 /           ; 0    nul             U+0000
             %x62 /           ; b    backspace       U+0008
             %x66 /           ; f    form feed       U+000C
             %x6E /           ; n    line feed       U+000A
             %x72 /           ; r    carriage return U+000D
             %x74 /           ; t    tab             U+0009
             %x76 /           ; v    vtab            U+000B
             %x75 4HEXDIG /   ; uXXXX                U+XXXX
             %x75 %x7B 1*HEXDIG %x7D )
                              ; u{X...}              U+X...

escape = %x5C                 ; \
d-quote = %x22                ; "
s-quote = %x27                ; '

unescaped = %x20-21 / %x23-26 / %x28-5B / %x5D-7E / %x80-10FFFF

binary = b-value *( value-concat b-value )

b-value = dollar [ b-string / b-direct ]

b-string = b-s-string / b-d-string

b-d-string = d-quote *( b-char / s-quote ) d-quote
b-s-string = s-quote *( b-char / d-quote ) s-quote

b-char = b-unescaped /
         escape (
             %x22 /           ; "    double quote    0x22
             %x27 /           ; '    single quote    0x27
             %x5C /           ; \    reverse solidus 0x5C
             %x2F /           ; /    solidus         0x2F
             %x30 /           ; 0    nul             0x00
             %x62 /           ; b    backspace       0x08
             %x66 /           ; f    form feed       0x0C
             %x6E /           ; n    line feed       0x0A
             %x72 /           ; r    carriage return 0x0D
             %x74 /           ; t    tab             0x09
             %x76 /           ; v    vtab            0x0B
             %x78 2HEXDIG )   ; xXX                  0xXX

b-unescaped = %x20-21 / %x23-26 / %x28-5B / %x5D-7E

b-direct = b-part *( dot b-part )

b-part = 1*b-byte

b-byte = 2HEXDIG

dollar = %x24                 ; $
dot = %x2E                    ; .

array = begin-array
        [ value *( value-separator value ) value-sep-opt ]
        end-array

object = begin-object
         [ member *( value-separator member ) value-sep-opt ]
         end-object

member = key name-separator value

key = string / identifier

identifier = i-begin *i-continue

i-begin = ALPHA / %x5F
i-continue = i-begin / DIGIT

value = false / null / true / object / array / number / string / binary

JAXN-text = ws value ws
