JSON is specified in three places:
The ECMA and IETF specifications are intended to specify the same JSON language, with mutual agreement to correct any differences that may be discovered.
The ECMA 404 standard uses a “railway track” diagram format to specify the syntax, but it is reasonably easy to construct Grit grammar rules from these diagrams.
The grammar rules specified in IETF 8259 use the IETF standard ABNF grammar rule format, which can be translated into equivalent Grit grammar rules.
The grammar rules specified in Douglas Crockfors’s original web-page are easily transcribed into Grit grammar rules:
This Grit grammar is easy to read and understand, and it corresponds directly with the JSON specification. The advantage of the Grit version is that it can be automatically executed as a parser.
Action functions can be added to translate the rule results into JavaScript data structures:
There is a problem with translating the JSON “null” value into a JavaScript null value. A null value can not be returned by an action function since that would be interpreted as the rule failing to match the input text.
For this reason the JSON “null” value is interpreted as a JavaScript undefined value. This is not an unreasonable JavaScript interpretation of a JSON “null” value. However, in this implementation the values and members functions substitute the null value for any undefined values in the resulting JavaScript data structures.
There is a small defect in the JSON specification for JavaScript strings. JSON allows the Unicode line terminators U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR to appear unescaped in quoted strings, these characters are illegal in JavaScript strings (ECMAScript).
Of course there are standard JSON parsers for JavaScript and many other programming languages that are well supported and battle tested. The Grit version is just a demonstration, to show that it is simple to implement and easy to understand. It follows directly from the specifications, and the resulting parser is practical and efficient.
For comparison here are the original JSON grammar rule specifications:
json
element
value
object
array
string
number
"true"
"false"
"null"
object
'{' ws '}'
'{' members '}'
members
member
member ',' members
member
ws string ws ':' element
array
'[' ws ']'
'[' elements ']'
elements
element
element ',' elements
element
ws value ws
string
'"' characters '"'
characters
""
character characters
character
'0020' . '10ffff' - '"' - '\'
'\' escape
escape
'"'
'\'
'/'
'b'
'f'
'n'
'r'
't'
'u' hex hex hex hex
hex
digit
'A' . 'F'
'a' . 'f'
number
integer fraction exponent
integer
digit
onenine digits
'-' digit
'-' onenine digits
digits
digit
digit digits
digit
'0'
onenine
onenine
'1' . '9'
fraction
""
'.' digits
exponent
""
'E' sign digits
'e' sign digits
sign
""
'+'
'-'
ws
""
'0020' ws
'000D' ws
'000A' ws
'0009' ws
" smart ' smart