eclog = ws ( object | [ pair-list ] ) ws object = '{' ws [ pair-list ] ws '}' array = '[' ws [ value-list ] ws ']' pair-list = pair *( separator pair ) [ ws ',' ] value-list = value *( separator value ) [ ws ',' ] pair = string ws ':' ws value value = object | array | string | number | boolean | null separator = ( ws ',' ws ) | ( wsp line-break ws ) string = unquoted-string | ( non-unquoted-string *( ws '+' ws non-unquoted-string ) ) non-unquoted-string = quoted-string | raw-string | heredoc-string quoted-string = '"' *( unescaped | '\' escape ) '"' unescaped = %x09 | %x20-21 | %x23-5B | %x5D-10FFFF escape = '"' | '\' | '/' | 'b' | 'f' | 'n' | 'r' | 't' | 'u' 4hex | 'u' '{' 1*6hex '}' unquoted-string = ( letter | '_' ) *( letter | digit | '_' | '-' | '.' ) raw-string = '@' delimiter0-16 '"' *char '"' delimiter0-16 heredoc-string = '|' delimiter1-16 line-break *( *char line-break ) wsp delimiter1-16 line-break char = %x09 | %x20-10FFFF delimiter0-16 = *16( letter | digit | '_' ) delimiter1-16 = 1*16( letter | digit | '_' ) number = [ sign ] ( ( significand [ exponent ] ) | "inf" | "nan" ) significand = integer [ fractional ] integer = '0' | ( digit1-9 *digit ) fractional = '.' 1*digit exponent = e [ sign ] ( '0' | ( digit1-9 *digit ) ) sign = '+' | '-' letter = 'A'-'Z' | 'a'-'z' digit = '0'-'9' digit1-9 = '1'-'9' hex = digit | 'A'-'F' | 'a'-'f' e = 'e' | 'E' boolean = "true" | "false" null = "null" ws = *( %x20 | %x09 | %x0D | %x0A ) wsp = *( %x20 | %x09 ) line-break = %x0D | %x0A | %x0D %x0A