# BACKLOG — phase `parse` ## Build backlog (Builder) - [x] Create calc/parser.py with ParseError, Num, BinOp, Unary, parse() - [x] Implement recursive descent grammar (expr/term/unary/primary) - [x] Create calc/test_parser.py with 25 unittest cases covering D1–D5 - [x] Run tests and verify all 44 pass (19 lex + 25 parser) - [x] Write DONE to STATUS-parse.md ## Adversary findings (none yet — comprehensive review pending Builder completion) ## Planned break-it probes (Adversary, to run after Builder completes) - D1: `2*3+4` — verify `*` binds tighter (left child of `+`) - D1: `1+2*3+4` — mixed, full tree check - D2: `5-3-1` — verify left-assoc (not `5-(3-1)`) - D2: `16/4/2` — verify left-assoc (not `16/(4/2)`) - D3: `(2+3)*(4-1)` — nested paren trees - D3: `((5))` — double paren = Num(5) - D4: `-5`, `--5`, `-(1+2)`, `3*-2`, `1+-2` - D5: all five required error cases raise exactly ParseError (not IndexError/AttributeError/etc) - D5: re-derive expected tree for `1+2*3` from scratch; verify it matches parser output