Editor

JSON Parser

#487 · Parsing · Expert · 260 XP · about 60 min

JSON is the text format most web services use to send data. Write parse_json(text) that turns a JSON document into Python values without using the json module, and raises ValueError if the text is not valid JSON.

The values, and what they become:

  • null, true and false become None, True and False.
  • A number becomes an int when it has no fraction and no exponent, and a float otherwise. Convert the number's text with int() or float(), so 2.5e3 gives 2500.0.
  • A string in double quotes becomes a str.
  • An array, [ then values separated by commas then ], becomes a list.
  • An object, { then "key": value pairs separated by commas then }, becomes a dict with the keys in the order they appear. If a key appears twice, the later value wins and the key keeps its first place.

The strict rules. Breaking any of them makes the text invalid:

  • A number is an optional -, then 0 or a digit 1 to 9 followed by more digits, then optionally . and one or more digits, then optionally e or E, an optional + or -, and one or more digits. So 01, 1., .5, +1 and 1e are all invalid.
  • Inside a string, a backslash must start one of the escapes \", \\, \/, \b, \f, \n, \r, \t, or \u followed by exactly four hex digits. A \u escape for a high surrogate (D800 to DBFF) followed by a \u escape for a low surrogate (DC00 to DFFF) makes one character, as in "😀".
  • Characters with codes below 32, such as a raw tab or line break, may not appear inside a string.
  • Object keys must be strings. A comma must sit between two items, never before a closing bracket or brace.
  • Whitespace (space, tab, \n and \r only) may appear before and after any value, comma or colon. The whole text must be one value, with nothing else after it.

Examples

parse_json('{"name": "Ada", "age": 36, "langs": ["en", "fr"]}')
# returns {'name': 'Ada', 'age': 36, 'langs': ['en', 'fr']}
parse_json('[1, -2.5, 3e2, true, false, null]')
# returns [1, -2.5, 300.0, True, False, None]
parse_json('"tab\\there \\u00e9"')
# returns 'tab\there é'
parse_json('[1, 2,]')
# raises ValueError

Constraints

  • text has at most 500,000 characters.
  • Arrays and objects nest at most 100 levels deep.
  • In the tests, surrogates always come in valid pairs.

Fastest solvers

Leaderboard

First solves only, ranked by stars and then time.