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