;; The ZOMB file format grammar in ABNF format.
;;
;; This ABNF definition of ZOMB is heavily influenced by the TOML ABNF found at:
;;      https://github.com/toml-lang/toml/blob/master/toml.abnf
;;
;; Credit to http://instaparse.mojombo.com/ as it was used for testing.

;; Top-Level Rules

zomb-file = decl *( separator decl ) [ separator ]

decl = kv-pair / macro-def / comment

;; Key-Value Pair Rules

kv-pair = string [ padding ] equals [ padding ] value

macro-kv-pair = string [ padding ] equals [ padding ] macro-value

;; Object Rules

object = object-begin [ padding ] [ kv-pair-list ] object-end

macro-object = object-begin [ padding ] [ macro-kv-pair-list ] object-end

;; Array Rules

array = array-begin [ padding ] [ value-list ] array-end

array-req = array-begin [ padding ] value-list array-end

macro-array = array-begin [ padding ] [ macro-value-list ] array-end

macro-array-req = array-begin [ padding ] macro-value-list array-end

batch-macro-arg-array = array-begin [ padding ] array-req-list array-end

batch-macro-macro-arg-array = array-begin [ padding ] macro-array-req-list array-end

;; Macro Expression Rules

macro-expr = macro-key [ macro-expr-params ] *( macro-accessor )

macro-macro-expr = macro-key [ macro-macro-expr-params ] *( macro-accessor )

batch-macro-expr = macro-key batch-macro-expr-params *( macro-accessor ) [ padding ] percent [ padding ] batch-macro-arg-array

batch-macro-macro-expr = macro-key batch-macro-macro-expr-params *( macro-accessor ) [ padding ] percent [ padding ] batch-macro-macro-arg-array

;; Macro Expression Param Rules

macro-expr-params = [ padding ] macro-params-begin [ padding ] value-list macro-params-end

macro-macro-expr-params = [ padding ] macro-params-begin [ padding ] macro-value-list macro-params-end

batch-macro-expr-params = [ padding ] macro-params-begin [ padding ] batch-param-list macro-params-end

batch-macro-macro-expr-params = [ padding ] macro-params-begin [ padding ] batch-macro-param-list macro-params-end

;; Macro Definition Rules

macro-def = macro-key [ padding ] [ macro-def-params ] [ padding ] equals [ padding ] macro-value

macro-def-params = macro-params-begin [ padding ] macro-param-list macro-params-end

macro-param-def = string [ padding ] equals [ padding ] value

;; Macro Utility Rules

macro-key = dollar string

macro-param-use = percent string

macro-accessor = dot string

;; Value and Concatenation Rules

value = string-val / object-val / array-val / macro-expr-val / batch-macro-expr-val

macro-value = macro-param-val / macro-string-val / macro-object-val / macro-array-val / macro-macro-expr-val / batch-macro-macro-expr-val

batch-param-value = question / value

batch-macro-param-value = question / macro-value

; NOTE: macro-expr and macro-param-use in the following rules must evaluate to the corresponding type

string-val = any-string *( plus ( any-string / macro-expr ) )

object-val = object *( plus ( object / macro-expr ) )

array-val = array *( plus ( array / macro-expr / batch-macro-expr ) )

macro-expr-val = macro-expr *( plus ( any-string / object / array / macro-expr / batch-macro-expr ) )

batch-macro-expr-val = batch-macro-expr *( plus ( array / macro-expr / batch-macro-expr ) )

batch-macro-macro-expr-val = batch-macro-macro-expr *( plus ( array / macro-expr / batch-macro-macro-expr ) )

macro-string-val = any-string *( plus ( any-string / macro-macro-expr / macro-param-use ) )

macro-object-val = macro-object *( plus ( macro-object / macro-macro-expr / macro-param-use ) )

macro-array-val = macro-array *( plus ( macro-array / macro-macro-expr / macro-param-use ) )

macro-macro-expr-val = macro-macro-expr *( plus ( any-string / macro-object / macro-array / macro-macro-expr / macro-param-use ) )

macro-param-val = macro-param-use *( plus ( any-string / macro-object / macro-array / macro-macro-expr / macro-param-use ) )

;; List Rules

kv-pair-list = kv-pair *( separator kv-pair ) [ separator ]

value-list = value *( separator value ) [ separator ]

array-req-list = array-req *( separator array-req ) [ separator ]

macro-array-req-list = macro-array-req *( separator macro-array-req ) [ separator ]

macro-param-list = string *( separator string ) [ separator [ macro-param-def-list ] ]

macro-param-def-list = macro-param-def *( separator macro-param-def ) [ separator ]

macro-kv-pair-list = macro-kv-pair *( separator macro-kv-pair ) [ separator ]

macro-value-list = macro-value *( separator macro-value ) [ separator ]

value-list-req-sep = value *( separator value ) separator

; NOTE: implementations must require at least one `?` in this list
batch-param-list = batch-param-value *( separator batch-param-value ) [ separator ]

batch-macro-param-list = batch-macro-param-value *( separator batch-macro-param-value ) [ separator ]

;; String Rules

string = bare-string / quoted-string

any-string = string / raw-string

bare-string = 1*( non-delimiter )

quoted-string = DQUOTE escaped-string DQUOTE

escaped-string = *( non-escaped / ( %x5C escaped ) )

raw-string = raw-line *( newline [ padding ] raw-line )

raw-line = %x5C.5C *any

non-delimiter = %x21 / %x23 / %x26-27 / %x2A / %x2D / %x2F-3C / %x3E / %x40-5A / %x5E-7A / %x7C / %x7E-10FFFF

;         "        \      b      f      n      r      t        uXXXX
escaped = DQUOTE / %x5C / %x62 / %x66 / %x6E / %x72 / %x74 / ( %x75 4HEXDIG )

non-escaped = WSP / %x21 / %x23-5B / %x5D-10FFFF

;; Comment Rule

comment = %x2F.2F *any

;; Special Delimiter Rules

dot = %x2E

dollar = %x24

equals = %x3D

plus = [ padding ] %x2B [ padding ]

comma = %x2C

percent = %x25

question = %x3F

object-begin = %x7B

object-end = %x7D

array-begin = %x5B

array-end = %x5D

macro-params-begin = %x28

macro-params-end = %x29

;; Other Rules

newline = LF / CRLF

padding = 1*( WSP / newline / ( comment newline ) )

separator = padding / ( [ padding ] comma [ padding ] )

any = WSP / %x21-10FFFF
