| // see https://spec.json5.org/#syntactic-grammar and |
| // https://spec.json5.org/#lexical-grammar |
| |
| COMMENT = _{ "/*" ~ (!"*/" ~ ANY)* ~ "*/" | "//" ~ (!line_terminator ~ ANY)* } |
| |
| WHITESPACE = _{ |
| "\u{0009}" | |
| "\u{000B}" | |
| "\u{000C}" | |
| "\u{0020}" | |
| "\u{00A0}" | |
| "\u{FEFF}" | |
| SPACE_SEPARATOR | |
| line_terminator |
| } |
| |
| array = { "[" ~ "]" | "[" ~ value ~ ("," ~ value)* ~ ","? ~ "]" } |
| |
| boolean = @{ "true" | "false" } |
| |
| char_escape_sequence = @{ single_escape_char | non_escape_char } |
| |
| char_literal = @{ !("\\" | line_terminator) ~ ANY } |
| |
| decimal_integer_literal = _{ "0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* } |
| |
| decimal_literal = _{ |
| decimal_integer_literal ~ "." ~ ASCII_DIGIT* ~ exponent_part? | |
| "." ~ ASCII_DIGIT+~ exponent_part? | |
| decimal_integer_literal ~ exponent_part? |
| } |
| |
| double_quote_char = _{ |
| "\\" ~ escape_sequence | |
| line_continuation | |
| !"\"" ~ char_literal |
| } |
| |
| escape_char = _{ single_escape_char | ASCII_DIGIT | "x" | "u" } |
| |
| escape_sequence = _{ |
| char_escape_sequence | |
| nul_escape_sequence | |
| "x" ~ hex_escape_sequence | |
| "u" ~ unicode_escape_sequence |
| } |
| |
| exponent_part = _{ ^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+ } |
| |
| hex_escape_sequence = @{ ASCII_HEX_DIGIT{2} } |
| |
| hex_integer_literal = _{ ^"0x" ~ ASCII_HEX_DIGIT+ } |
| |
| identifier = ${ identifier_start ~ identifier_part* } |
| |
| identifier_part = _{ |
| identifier_start | |
| &( |
| NONSPACING_MARK | |
| DIACRITIC | // not sure about this, spec says "Combining spacing mark (Mc)" |
| DECIMAL_NUMBER | |
| CONNECTOR_PUNCTUATION | |
| "\u{200C}" | |
| "\u{200D}" |
| ) ~ char_literal |
| } |
| |
| identifier_start = _{ |
| &(unicode_letter | "$" | "_") ~ char_literal | |
| "\\u" ~ unicode_escape_sequence |
| } |
| |
| key = _{ identifier | string } |
| |
| line_continuation = _{ "\\" ~ line_terminator_sequence } |
| |
| line_terminator = _{ "\u{000A}" | "\u{000D}" | "\u{2028}" | "\u{2029}" } |
| |
| line_terminator_sequence = _{ "\u{000D}" ~ "\u{000A}" | line_terminator } |
| |
| non_escape_char = _{ !(escape_char | line_terminator) ~ ANY } |
| |
| nul_escape_sequence = @{ "0" } |
| |
| null = @{ "null" } |
| |
| number = @{ ("+" | "-")? ~ numeric_literal } |
| |
| numeric_literal = _{ |
| hex_integer_literal | |
| decimal_literal | |
| "Infinity" | |
| "NaN" |
| } |
| |
| object = { "{" ~ "}" | "{" ~ pair ~ ("," ~ pair)* ~ ","? ~ "}" } |
| |
| pair = _{ key ~ ":" ~ value } |
| |
| single_escape_char = _{ "'" | "\"" | "\\" | "b" | "f" | "n" | "r" | "t" | "v" } |
| |
| single_quote_char = _{ |
| "\\" ~ escape_sequence | |
| line_continuation | |
| !"'" ~ char_literal |
| } |
| |
| string = ${ "\"" ~ double_quote_char* ~ "\"" | "'" ~ single_quote_char* ~ "'" } |
| |
| text = _{ SOI ~ value ~ EOI } |
| |
| unicode_escape_sequence = @{ ASCII_HEX_DIGIT{4} } |
| |
| unicode_letter = _{ |
| UPPERCASE_LETTER | |
| LOWERCASE_LETTER | |
| TITLECASE_LETTER | |
| MODIFIER_LETTER | |
| OTHER_LETTER | |
| LETTER_NUMBER |
| } |
| |
| value = _{ null | boolean | string | number | object | array } |