JSON parser grammar

Garrett Smith dhtmlkitchen at gmail.com
Tue Jun 22 17:28:39 PDT 2010


On 6/3/09, Douglas Crockford <douglas at crockford.com> wrote:
> Allen Wirfs-Brock wrote:
>>> JSON.parse("[010]")
>>>
>>> should be an error, per spec. Nobody follows the spec though...
>>>
>>
>> As I read them neither the RFC or the current ES5 JSON grammar recognize
>> "[010]" as a valid JSON form, so according to the ES5 spec. a syntax error
>> should be thrown.  If we really want all implementation to accept "010" as
>> a JSONNumber then we should specify it as such.  Of course we have to
>> define what it means (decimal, octal??).
>>
>> My inclination would be to require ES5 implementation to exactly conform
>> the whatever JSON grammar we provide and to throw syntax errors if the
>> input doesn't exactly conform to the grammar. (in other say that the
>> section 16 extension allowance doesn't apply to JSON.parse.  If an
>> implementation wants to support JSON syntax extensions it could always do
>> so by providing a JSON.parseExtended function (or whatever they want to
>> call it) that uses an implementation defined grammar.
>
> I agree. It is not helpful to developers to allow weird forms on browser A
> but
> not on browser B. What should be allowed is clearly described in the E5
> spec.



On 6/3/09, Douglas Crockford <douglas at crockford.com> wrote:
> Allen Wirfs-Brock wrote:
>>> JSON.parse("[010]")
>>>
>>> should be an error, per spec. Nobody follows the spec though...
>>>
>>
>> As I read them neither the RFC or the current ES5 JSON grammar recognize
>> "[010]" as a valid JSON form, so according to the ES5 spec. a syntax error
>> should be thrown.  If we really want all implementation to accept "010" as
>> a JSONNumber then we should specify it as such.  Of course we have to
>> define what it means (decimal, octal??).
>>
>> My inclination would be to require ES5 implementation to exactly conform
>> the whatever JSON grammar we provide and to throw syntax errors if the
>> input doesn't exactly conform to the grammar. (in other say that the
>> section 16 extension allowance doesn't apply to JSON.parse.  If an
>> implementation wants to support JSON syntax extensions it could always do
>> so by providing a JSON.parseExtended function (or whatever they want to
>> call it) that uses an implementation defined grammar.
>
> I agree. It is not helpful to developers to allow weird forms on browser A
> but
> not on browser B. What should be allowed is clearly described in the E5
> spec.

That's right.

A wrapper for JSON should be consistent and if native JSON support
isn't, then what does the wrapper do, follow the ES5 spec or follow
what the browsers do? What if no browsers follow the spec? Does that
mean we can't use native JSON at all?

The wrapper can use capability checks to determine if native JSON is
buggy and if it is, use a fallback. I've provided a sample capability
test below, for those who don't know what I mean.

Most of the questions on Grammar were answered in this thread,
however, the question of  U+0009 as a JSONStringCharacter remains. All
major browsers allowi U+0009 in JSONString. What should the capability
test check? If all major browsers parse without error '  "\t"  ' to
result in a string with the character U+0009, then the feature test
can detect that failing and use the fallback.

JSON.parse accepting U+0009 in strings is now part of public API and
major libraries rely on that. Is going to be codified?

To summarize, the pressing questions are:

1) Is the spec going to change to allow U+0009? And if it isn't, why not? and
2) What should the fallback for JSON.parse use? Should it:
 (a) go by the letter of the spec and perform a capability test to
expect that an error is thrown for JSON.parse('  "\t"  '), or
 (b) go with what seems to be a de facto standard and allow U+0009 as
JSONStringCharacter?

There is a need to answer these questions so that code can be written
using JSON. It's not just an academic exercise here. I would like to
provide an advisable solution as an FAQ Entry the comp.lang.javascript
FAQ.

Example of a feature test:

// Incomplete and untested.
var IS_JSON_PARSE_SUPPORTED = function() {
  var IS_JSON_PARSE_SUPPORTED = typeof JSON == "object"
     && typeof JSON.parse == "function"
    && isJSONParserCompliant();

  function isJSONParserCompliant() {
    // TODO: add more checks for known failings
    // in major implementations.
    return canParseNumbers();
  }

  function canParseNumbers() {
    try {
      JSON.parse("010");
      return false; // error expected.
    } catch(ex) { }
    return true;
  }
  return IS_JSON_PARSE_SUPPORTED;
}();

Garrett


More information about the es-discuss mailing list