Skip to content
Parsing Objects
step 1/5

Reading — step 1 of 5

Read

~2 min readContainers: Arrays & Objects

Parsing Objects

object = "{" [ member *( "," member ) ] "}"
member = string ":" value

Same comma discipline as arrays, plus one extra obligation per member: a string key, then :, then a value.

parseObject():
    expect "{"
    obj = {}
    if peek() == "}": consume(); return obj
    while True:
        key = expectString()      # must be a STRING token, not a bare word
        expect ":"
        obj[key] = parseValue()
        if peek() == ",": consume(); continue
        break
    expect "}"
    return obj

The rules people get wrong

Keys are quoted strings — always. {name: "alice"} is JavaScript, not JSON. The token after { (or after a member's comma) must be a STRING; anything else is an error. Numbers can't be keys either: {1: "x"} is invalid — you must write {"1": "x"}.

Duplicate keys are legal but poisonous. RFC 8259 says names within an object "SHOULD be unique" — SHOULD, not MUST — and explicitly leaves the behavior for duplicates unspecified. In practice most parsers silently keep the last value (json.loads('{"a":1,"a":2}') gives {'a': 2}); a few keep the first, a few error. Security folks care: two parsers disagreeing about which value "wins" for {"role":"user","role":"admin"} is a real vulnerability class. The natural dict-assignment in the algorithm above gives you last-wins.

Objects are unordered — officially. The spec calls an object an unordered collection, so no conforming producer/consumer may attach meaning to member order. In practice Python dicts preserve insertion order and JavaScript objects mostly do too, which lulls people into relying on it; the moment a document passes through a parser that reorders or sorts, that assumption dies.

Trailing commas: same as arrays. After a comma you owe a member; if } shows up instead, that is the trailing-comma error.

One practical aside: once values nest, you need a way to name a location — JSON Pointer (RFC 6901) is the standard: /users/0/name means data["users"][0]["name"]. Good error messages and JSON Schema validators both speak it.

Your exercise

Parse one object per line and print it with keys sorted alphabetically — the harness's repr_sorted already does the sorting and formatting; your job is to return a plain dict (hidden test: {"z": 1, "a": 2} prints {'a': 2, 'z': 1}). The grader-caught mistakes are the two exact error strings: {name: "bare ident"} must print ERR object key must be a string — check that the token in key position is a string before consuming it — and {"x": 1,} must print ERR trailing comma. Values recurse through your full parseValue, so {"a": [1, 2], "b": {"c": true}} must print {'a': [1, 2], 'b': {'c': True}} and the doubly nested {"nested": {"a": {"b": 1}}} must survive intact.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…