Formal Grammar
The complete formal grammar specification for JSON6 implementers and language enthusiasts.
TL;DR: This page contains the formal grammar specification for JSON6 in ABNF notation. It's primarily intended for implementers building JSON6 parsers or tools.
Grammar Notation
This specification uses a modified ABNF (Augmented Backus-Naur Form) notation similar to that used in ECMAScript specifications.
Notation Conventions
| Notation | Meaning | Example |
|---|---|---|
A B | A followed by B (concatenation) | { } means { then } |
A | B | A or B (alternation) | true | false |
A? | Zero or one A (optional) | Sign? optional sign |
A* | Zero or more A | Digit* any digits |
A+ | One or more A | Digit+ at least one digit |
"text" | Literal text | "null" the word null |
[a-z] | Character range | [0-9] digits 0-9 |
<NAME> | Unicode category or named character | <TAB> tab character |
JSON6 Values
A JSON6 document consists of a single JSON6 value optionally surrounded by whitespace and comments.
Value Productions
JSON6Text : JSON6Value JSON6Value : JSON6Null JSON6Boolean JSON6String JSON6Number JSON6Object JSON6Array JSON6Null : "null" JSON6Boolean : "true" "false"Note: Unlike JSON, which only allows objects or arrays at the top level, JSON6 allows any value type as the root element.
Object Grammar
Objects are unordered collections of key-value pairs enclosed in curly braces.
Object Productions
JSON6Object : "{" "}" "{" JSON6MemberList "}" "{" JSON6MemberList "," "}" JSON6MemberList : JSON6Member JSON6MemberList "," JSON6Member JSON6Member : JSON6MemberName ":" JSON6Value JSON6MemberName : JSON6Identifier JSON6StringIdentifier Grammar
JSON6Identifier : IdentifierName IdentifierName : IdentifierStart IdentifierName IdentifierPart IdentifierStart : UnicodeLetter "$" "_" "\" UnicodeEscapeSequence IdentifierPart : IdentifierStart UnicodeCombiningMark UnicodeDigit UnicodeConnectorPunctuation <ZWNJ> <ZWJ> UnicodeLetter : any character in Unicode categories "Lu" "Ll" "Lt" "Lm" "Lo" "Nl" UnicodeDigit : any character in Unicode category "Nd" UnicodeCombiningMark : any character in Unicode categories "Mn" "Mc" UnicodeConnectorPunctuation : any character in Unicode category "Pc"Array Grammar
Arrays are ordered sequences of values enclosed in square brackets.
Array Productions
JSON6Array : "[" "]" "[" JSON6ElementList "]" "[" JSON6ElementList "," "]" JSON6ElementList : JSON6Value JSON6ElementList "," JSON6ValueString Grammar
Strings can use single or double quotes and support various escape sequences.
String Productions
JSON6String : '"' JSON6DoubleStringCharacter? '"' "'" JSON6SingleStringCharacter? "'" JSON6DoubleStringCharacter : JSON6DoubleStringCharacter JSON6DoubleStringCharacter? JSON6SingleStringCharacter : JSON6SingleStringCharacter JSON6SingleStringCharacter? JSON6DoubleStringCharacter : SourceCharacter but not '"' or "\" or LineTerminator "\" EscapeSequence LineContinuation <LS> <PS> JSON6SingleStringCharacter : SourceCharacter but not "'" or "\" or LineTerminator "\" EscapeSequence LineContinuation <LS> <PS> LineContinuation : "\" LineTerminatorSequenceEscape Sequences
EscapeSequence : CharacterEscapeSequence "0" [lookahead not in DecimalDigit] HexEscapeSequence UnicodeEscapeSequence CharacterEscapeSequence : SingleEscapeCharacter NonEscapeCharacter SingleEscapeCharacter : "'" | '"' | "\" | "b" | "f" | "n" | "r" | "t" | "v" NonEscapeCharacter : SourceCharacter but not EscapeCharacter or LineTerminator EscapeCharacter : SingleEscapeCharacter DecimalDigit "x" "u" HexEscapeSequence : "x" HexDigit HexDigit UnicodeEscapeSequence : "u" HexDigit HexDigit HexDigit HexDigit HexDigit : [0-9a-fA-F]Number Grammar
Numbers can be decimal or hexadecimal, and include special values like Infinity and NaN.
Number Productions
JSON6Number : JSON6NumericLiteral "Infinity" "NaN" JSON6NumericLiteral : NumericLiteral "+" NumericLiteral "-" NumericLiteral NumericLiteral : DecimalLiteral HexIntegerLiteral DecimalLiteral : DecimalIntegerLiteral "." DecimalDigits? ExponentPart? "." DecimalDigits ExponentPart? DecimalIntegerLiteral ExponentPart? DecimalIntegerLiteral : "0" NonZeroDigit DecimalDigits? DecimalDigits : DecimalDigit DecimalDigits DecimalDigit DecimalDigit : [0-9] NonZeroDigit : [1-9] ExponentPart : ExponentIndicator SignedInteger ExponentIndicator : "e" | "E" SignedInteger : DecimalDigits "+" DecimalDigits "-" DecimalDigits HexIntegerLiteral : "0x" HexDigit+ "0X" HexDigit+ Note: Unlike JSON, JSON6 allows leading decimal points (.5), trailing decimal points (5.), explicit positive signs (+5), and hexadecimal literals (0xFF).
Lexical Grammar
Whitespace, line terminators, and comments that separate tokens.
Whitespace
WhiteSpace : <TAB> U+0009 Tab <VT> U+000B Vertical Tab <FF> U+000C Form Feed <SP> U+0020 Space <NBSP> U+00A0 No-Break Space <BOM> U+FEFF Byte Order Mark <USP> Any Unicode "Zs" category characterLine Terminators
LineTerminator : <LF> U+000A Line Feed <CR> U+000D Carriage Return <LS> U+2028 Line Separator <PS> U+2029 Paragraph Separator LineTerminatorSequence : <LF> <CR> [lookahead not in <LF>] <LS> <PS> <CR> <LF>Comments
Comment : MultiLineComment SingleLineComment MultiLineComment : "/*" MultiLineCommentChars? "*/" MultiLineCommentChars : MultiLineNotAsteriskChar MultiLineCommentChars? "*" PostAsteriskCommentChars? PostAsteriskCommentChars : MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentChars? "*" PostAsteriskCommentChars? MultiLineNotAsteriskChar : SourceCharacter but not "*" MultiLineNotForwardSlashOrAsteriskChar : SourceCharacter but not "/" or "*" SingleLineComment : "//" SingleLineCommentChars? SingleLineCommentChars : SingleLineCommentChar SingleLineCommentChars? SingleLineCommentChar : SourceCharacter but not LineTerminatorReserved Words as Keys
Reserved words are valid unquoted object keys in JSON6. The JSON6Identifier production above is IdentifierName with no exclusion, and ECMAScript 5.1 defines IdentifierName to include every reserved word. So { class: 'container' } and { null: 1 } parse, and both the JavaScript and the Python reference implementations accept them.
These are the words ECMAScript 5.1 reserves for its own grammar. JSON6 permits all of them as unquoted keys:
ReservedWord : Keyword FutureReservedWord NullLiteral BooleanLiteral Keyword : "break" "case" "catch" "continue" "debugger" "default" "delete" "do" "else" "finally" "for" "function" "if" "in" "instanceof" "new" "return" "switch" "this" "throw" "try" "typeof" "var" "void" "while" "with" FutureReservedWord : "class" "const" "enum" "export" "extends" "import" "super" FutureReservedWord (strict mode) : "implements" "interface" "let" "package" "private" "protected" "public" "static" "yield" NullLiteral : "null" BooleanLiteral : "true" "false" Style note: Quoting a reserved word is optional, not required - { class: 'value' }, { "class": "value" } and { 'class': 'value' } all parse to the same object. Quote it when you want the key to read unambiguously to someone skimming the file. What genuinely cannot be unquoted is a key that is not an IdentifierName at all: { 'my-key': 1 }, { '123abc': 1 } and { 'has spaces': 1 } must be quoted.
Building a JSON6 Parser?
Check out the reference implementation or explore language-specific libraries.