A JSON parser
Stage 6 of 7v3 · 9d008f00

Objects and complete documents

Add key-value pairs and complete the recursive grammar.

The project contract

Your program must read one JSON document from standard input. If it is valid, write that same value to standard output serialized as compact JSON and exit with code 0. If it is not valid, write nothing to stdout, explain the error on stderr and exit with a code other than 0.

The tester runs, from the project root, the commands you declare in shipcode.yml:

challenge: json-parser
build: your-build-command # optional
run: your-run-command

Do not use your standard library's JSON parser, nor an equivalent dependency. You may use its data types and a serializer at the end: what you are building is the lexical and syntactic analysis.

Your goal

Implement objects: a key is always a string, then comes a colon, then any JSON value. Members are separated by commas, and the empty object is valid.

Observable decisions

JSON allows repeated keys even though it does not define what they mean. For this project keep the last one; document that decision. The output order of the keys is not evaluated semantically, but your serialization must remain valid JSON.

Your value function now covers the seven possible beginnings: n, t, f, a number, a quote, a bracket and a brace. Any other character is an error with a useful position.

An object is a sequence with extra rules

Each member has a string key, a colon, and a value. Consume {, handle the empty object, require a string key, require :, parse any JSON value, and then require a comma or }. After a comma, require another key.

Reuse your string parser for keys and your general value parser for values. With objects, you can now represent every JSON document recursively.

For duplicate keys, keep the last value and document that project decision. Continue checking for trailing content after the root object closes.

When debugging, name the thing you expected: key, colon, value, comma, or close.

Before the tests

Try {}, one pair, nested objects, an array value, {a:1}, {"a" 1}, {"a":}, {"a":1,}, and {}[].

Acceptance criteria

  • Accepts empty objects, nested ones and combinations with arrays.
  • Requires string keys, colons and correct separators.
  • Ignores only the whitespace allowed between tokens.
  • Rejects every character after the root value.

Run shipcode test --stage 05-objetos.