A JSON parser
Stage 7 of 7v3 · 9734c64e

Useful errors and hardening

Turn the working parser into a reliable tool.

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

Your parser already covers the grammar. Now make it usable: errors with line, column and cause; controlled limits; a full read of stdin; and a regression suite of your own.

An error is an interface too

Keep the offset of the failure and derive line and column when you build the diagnostic. Distinguish at least unexpected end, unexpected token, invalid escape and exceeded depth. The contract only requires the word error, but a person needs to know where to fix things.

Use a corpus of small valid and invalid documents. If your language ships a JSON serializer, you may compare structures with it in internal tests, without using its parser in the implementation you deliver.

From “it works” to “people can use it”

Do not rewrite the parser. Improve cross-cutting behavior in separate changes: centralize errors, retain the failure offset, derive line and column, distinguish useful categories, add depth and size limits, build a regression suite, and document project decisions.

An offset is convenient internally; line, column, and a short context excerpt help a person. Distinguish unexpected end, unexpected token, invalid number or escape, missing separator, trailing content, and exceeded limits.

A regression suite keeps small valid and invalid examples from every stage. Add the smallest possible case whenever you fix a bug.

Run the program from a clean terminal. Stdout must contain only valid JSON; diagnostics belong on stderr. Ask another person to follow the README—questions reveal missing documentation.

Final checklist

All earlier valid cases pass; invalid input exits non-zero; errors never leave partial JSON on stdout; diagnostics include useful position and cause; limits fail safely; and the README explains build, run, test, and limitations.

Acceptance criteria

  • No invalid input exits with code 0.
  • stdout is reserved for valid results; diagnostics go to stderr.
  • Deep or large inputs fail in a controlled way according to your documented limits.
  • Every contract from the six stages passes in a single run.

Run shipcode test. When everything is green, you have finished a JSON parser from scratch: publish the repository and write down the design decisions in its README.