A JSON parser
Stage 4 of 7v3 · f11301ff

Strings, escapes and Unicode

Decode quotes, escaped characters and Unicode sequences.

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

Recognize strings delimited by double quotes. The result must hold the decoded characters, not the text of their escapes.

Two kinds of character

A regular character is copied unless it is a quote, a backslash or a U+0000–U+001F control. A backslash opens an escape: JSON's eight short escapes, or \u followed by exactly four hexadecimal digits.

Unicode adds a design decision. If your language represents text as code points, combine surrogate pairs correctly; if it uses UTF-16, make sure you do not accept a lone surrogate. A malformed escape must never turn silently into text.

Two different representations

Do not confuse JSON source text with the resulting value. The text "hello\nworld" contains a backslash and n, while the parsed value contains a newline. Decode escapes as you advance.

After the opening quote, repeatedly handle four cases: a closing quote finishes the string; a backslash starts an escape; a control character is an error; every other character is appended. End-of-input before a closing quote is also an error.

Implement plain strings first, then JSON's eight short escapes, then \uXXXX, and finally surrogate pairs. JSON rules are not your programming language's string-literal rules.

Common mistakes include preserving escapes instead of decoding them, accepting single quotes, allowing literal newlines, and mixing byte offsets with character offsets without a decision.

Before the tests

Try an empty string, ordinary text, \n, "\u0048ello", an escaped quote, "\x20", an unescaped newline, and an unterminated string.

Acceptance criteria

  • Accepts empty strings and direct Unicode characters.
  • Decodes quotes, slashes, escaped controls and \uXXXX.
  • Rejects unescaped line breaks, unknown escapes and unterminated strings.
  • Serializes back a valid JSON string.

Run shipcode test --stage 03-cadenas.