3.3 KiB
REVIEW — phase: parse (Adversary)
Verdict: ALL GATES PASS @2026-06-15T01:42:00Z
Cold-verified from commit 23d0ae9 (work-adv clone, fresh shell, no cached state).
D6 (tests green): PASS @2026-06-15T01:42:00Z
python -m unittest -q
Ran 41 tests in 0.001s
OK
41 tests (22 lexer + 19 parser), 0 failures. Tests assert on repr()/tree structure, not evaluation — satisfies the plan requirement.
D1 (precedence): PASS @2026-06-15T01:42:00Z
1+2*3 → BinOp(PLUS, Num(1), BinOp(STAR, Num(2), Num(3))) ✓
6-4/2 → BinOp(MINUS, Num(6), BinOp(SLASH, Num(4), Num(2))) ✓
Re-derived independently: grammar expr: term((+|-)term)* / term: unary((*|/)unary)* guarantees *// subtrees sit inside +/- nodes. Observed matches.
Extra adversarial probe:
1+2*3+4 → BinOp(PLUS, BinOp(PLUS, Num(1), BinOp(STAR, Num(2), Num(3))), Num(4)) ✓
D2 (left associativity): PASS @2026-06-15T01:42:00Z
8-3-2 → BinOp(MINUS, BinOp(MINUS, Num(8), Num(3)), Num(2)) ✓
8/4/2 → BinOp(SLASH, BinOp(SLASH, Num(8), Num(4)), Num(2)) ✓
Extra probes:
1+2+3 → BinOp(PLUS, BinOp(PLUS, Num(1), Num(2)), Num(3)) ✓
2*3*4 → BinOp(STAR, BinOp(STAR, Num(2), Num(3)), Num(4)) ✓
4*3/2 → BinOp(SLASH, BinOp(STAR, Num(4), Num(3)), Num(2)) ✓
Left-associativity correctly implemented via iterative while-loop (not recursion).
D3 (parentheses): PASS @2026-06-15T01:42:00Z
(1+2)*3 → BinOp(STAR, BinOp(PLUS, Num(1), Num(2)), Num(3)) ✓
((2)) → Num(2) ✓
(-5) → Unary(MINUS, Num(5)) ✓
D4 (unary minus): PASS @2026-06-15T01:42:00Z
-5 → Unary(MINUS, Num(5)) ✓
-(1+2) → Unary(MINUS, BinOp(PLUS, Num(1), Num(2))) ✓
3 * -2 → BinOp(STAR, Num(3), Unary(MINUS, Num(2))) ✓
--5 → Unary(MINUS, Unary(MINUS, Num(5))) ✓ (double unary)
2+-3 → BinOp(PLUS, Num(2), Unary(MINUS, Num(3))) ✓ (unary after binary)
Right-recursive _unary correctly handles chained negation.
D5 (errors raise ParseError): PASS @2026-06-15T01:42:00Z
All five required cases verified — each raises ParseError, not ValueError, IndexError, or any other exception:
'1 +' → ParseError: unexpected token 'EOF' ✓
'(1' → ParseError: expected ')', got 'EOF' ✓
'1 2' → ParseError: unexpected token 'NUMBER' after expression ✓
')(' → ParseError: unexpected token 'RPAREN' ✓
'' → ParseError: empty input ✓
Extra adversarial error probes (all raise ParseError):
'*5' → ParseError: unexpected token 'STAR' ✓
'5*' → ParseError: unexpected token 'EOF' ✓
'()' → ParseError: unexpected token 'RPAREN' ✓
'(+5)' → ParseError: unexpected token 'PLUS' ✓
'1++2' → ParseError: unexpected token 'PLUS' ✓
Summary
All six DoD gates D1–D6 independently verified cold. No defects found. The grammar in STATUS exactly matches the implementation (_expr/_term/_unary/_primary). Node shape is stable and documented in the parse() docstring. No veto.
Builder may write ## DONE to STATUS-parse.md.