Project 2: Custom JSON Parser
A JSON parser from scratch that tokenizes and parses JSON into Go data structures, without using
encoding/json.
Quick Reference
| Attribute | Value |
|---|---|
| Primary Language | Go |
| Alternative Languages | C, Rust, Zig |
| Difficulty | Level 2: Intermediate |
| Time Estimate | 1-2 weeks |
| Knowledge Area | Parsing, Lexical Analysis, Recursive Descent |
| Tooling | None (from scratch) |
| Prerequisites | Completed Project 1. Understand structs, slices, maps, and error handling. Familiarity with recursion. |
What You Will Build
A JSON parser from scratch that tokenizes and parses JSON into Go data structures, without using encoding/json.
Why It Matters
This project builds core skills that appear repeatedly in real-world systems and tooling.
Core Challenges
- Tokenizing (lexing) JSON → maps to string processing, runes, and state machines
- Recursive descent parsing → maps to function recursion and Go’s call stack
- Representing dynamic types → maps to interfaces and type assertions
- Handling edge cases → maps to error handling and Unicode support
Key Concepts
- Strings vs runes: “The Go Programming Language” Ch. 3.5 - Donovan & Kernighan
- Interfaces and type switches: “Learning Go” Ch. 7 - Jon Bodner
- Recursive descent: “Writing An Interpreter In Go” Ch. 2 - Thorsten Ball
- State machines: “Crafting Interpreters” Ch. 4 - Bob Nystrom (free online)
Real-World Outcome
$ echo '{"name": "Go", "year": 2009, "features": ["fast", "simple"]}' | ./jsonparser
Parsed successfully!
Type: Object
{
"name" (String): "Go"
"year" (Number): 2009
"features" (Array): [
(String): "fast"
(String): "simple"
]
}
$ echo '{"broken": }' | ./jsonparser
Parse error at position 11: unexpected token '}', expected value
$ ./jsonparser --tokens '{"x": 1}'
Tokens:
LEFT_BRACE {
STRING "x"
COLON :
NUMBER 1
RIGHT_BRACE }
EOF
Implementation Guide
- Reproduce the simplest happy-path scenario.
- Build the smallest working version of the core feature.
- Add input validation and error handling.
- Add instrumentation/logging to confirm behavior.
- Refactor into clean modules with tests.
Milestones
- Milestone 1: Minimal working program that runs end-to-end.
- Milestone 2: Correct outputs for typical inputs.
- Milestone 3: Robust handling of edge cases.
- Milestone 4: Clean structure and documented usage.
Validation Checklist
- Output matches the real-world outcome example
- Handles invalid inputs safely
- Provides clear errors and exit codes
- Repeatable results across runs
References
- Main guide:
LEARN_GO_DEEP_DIVE.md - “Writing An Interpreter In Go” by Thorsten Ball