; The JavaScript object Notation (JSON) Data Interchange Format
; https://tools.ietf.org/html/rfc7159

ABNF-Actions =
  ; Custom configuration
  to-language 'JSON'
  to-fileTypes ['json']
  to-scopeName 'source.json'
  to-description 'JSON to AST'

  ; Specific configuration
  to-locfield    'loc'   ; The field-name of location
  to-typefield   'type'  ; The field-name of type

  ; AST node type described.

  ; Structure
  Object (
    ; Fields Description.
    children  ARRAY<Property>
  )

  Array (
    children ARRAY<Object, Array, Literal>
  )

  Literal (
    value <null, BOOL, STRING, INT, FLOAT>
  )

  Identifier  (
    ; Declaration STRING type with initial value
    value  ''
  )

  Property    (
    key   <Identifier>
    value <Object, Array, Literal>
  )

JSON-text = ws value ws

value = object--Object(value)
      / array--Array(value)
      / string--Literal(value)
      / number--Literal(value)
      / boolean--Literal(value)
      / null--Literal(value)

object  =
  '{' ws [
      property--Property(children)
      *( ws ',' ws property--Property(children) )
  ] ws '}'

property =
  string--Identifier(key) ws ':' ws value

array  =
  '[' ws [ value *( ws ',' ws value ) ws ] ']'
  to--move(value, children)

number = number-val--pending(value)

number-val = [ '-' ] int (
    frac [ exp ] to--type(FLOAT)
    / exp to--type(FLOAT)
    / to--type(INT)
  )

exp = "E" [ '-' / '+' ] 1*DIGIT

frac = '.' 1*DIGIT

int = '0' / ( %x31-39 *DIGIT )

string    = '"' *char--STRING(value, unescape) '"'

boolean   = 'true' to--true(value) /
            'false' to--false(value)

null      = 'null' to--null(value)

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

char      = unescaped /
            '\' (
              '"' /          ; quotation mark  U+0022
              '\' /          ; reverse solidus U+005C
              '/' /          ; solidus         U+002F
              'b' /          ; backspace       U+0008
              'f' /          ; form feed       U+000C
              'n' /          ; line feed       U+000A
              'r' /          ; carriage return U+000D
              't' /          ; tab             U+0009
              'u' 4HEXDIG    ; uXXXX           U+XXXX
            )

unescaped = %x20-21 / %x23-5B / %x5D-10FFFF

DIGIT     = %x30-39 ; 0-9

HEXDIG    = DIGIT / %x41-5A / %x61-7A
