# REVIEW — Phase parse (Adversary) ## Status All gates PASS. Ready to approve ## DONE. ## Gate verdicts | Gate | Verdict | Timestamp | Evidence | |------|---------|-----------|----------| | D1 — precedence | PASS | 2026-06-15T00:22:39Z | See below | | D2 — left associativity | PASS | 2026-06-15T00:22:39Z | See below | | D3 — parentheses | PASS | 2026-06-15T00:22:39Z | See below | | D4 — unary minus | PASS | 2026-06-15T00:22:39Z | See below | | D5 — errors | PASS | 2026-06-15T00:22:39Z | See below | | D6 — tests green | PASS | 2026-06-15T00:22:39Z | Ran 45 tests in 0.001s OK | ## Cold-verification evidence ### D6 — tests green ``` python -m unittest -q Ran 45 tests in 0.001s OK ``` 21 lexer + 24 parser tests, 0 failures. ### D1 — precedence (cold AST shape check) ``` 1+2*3 → BinOp('+', Num(1), BinOp('*', Num(2), Num(3))) ✓ (* binds tighter) 2*3+4 → BinOp('+', BinOp('*', Num(2), Num(3)), Num(4)) ✓ 10-6/2 → BinOp('-', Num(10), BinOp('/', Num(6), Num(2))) ✓ ``` Independently derived: `1+2*3` must have `+` at root with `*` in right child — confirmed. ### D2 — left associativity (cold AST shape check) ``` 8-3-2 → BinOp('-', BinOp('-', Num(8), Num(3)), Num(2)) ✓ (left-assoc) 8/4/2 → BinOp('/', BinOp('/', Num(8), Num(4)), Num(2)) ✓ 1+2+3 → BinOp('+', BinOp('+', Num(1), Num(2)), Num(3)) ✓ 2*3*4 → BinOp('*', BinOp('*', Num(2), Num(3)), Num(4)) ✓ 1-2-3 → BinOp('-', BinOp('-', Num(1), Num(2)), Num(3)) ✓ (break-it: not right-assoc) ``` Iterative while-loop in `_expr`/`_term` enforces left-assoc by construction. ### D3 — parentheses (cold AST shape check) ``` (1+2)*3 → BinOp('*', BinOp('+', Num(1), Num(2)), Num(3)) ✓ 3*(1+2) → BinOp('*', Num(3), BinOp('+', Num(1), Num(2))) ✓ ((4)) → Num(4) ✓ 8-(3-2) → BinOp('-', Num(8), BinOp('-', Num(3), Num(2))) ✓ ((((1+2)))) → BinOp('+', Num(1), Num(2)) ✓ (deep nesting) ``` ### D4 — unary minus (cold AST shape check) ``` -5 → Unary('-', Num(5)) ✓ -(1+2) → Unary('-', BinOp('+', Num(1), Num(2))) ✓ 3 * -2 → BinOp('*', Num(3), Unary('-', Num(2))) ✓ --5 → Unary('-', Unary('-', Num(5))) ✓ 1 + -2 → BinOp('+', Num(1), Unary('-', Num(2))) ✓ ---5 → Unary('-', Unary('-', Unary('-', Num(5)))) ✓ (break-it: triple unary) 6 / -2 → BinOp('/', Num(6), Unary('-', Num(2))) ✓ (break-it: unary in denom) ``` `_unary` is right-recursive: `'-' _unary | _primary` — correct for unary. ### D5 — errors (cold: all five plan cases + extras) ``` '1 +' → OK ParseError '(1' → OK ParseError '1 2' → OK ParseError ')(' → OK ParseError '' → OK ParseError '*' → OK ParseError (break-it) ')' → OK ParseError (break-it) '1+2)' → OK ParseError (break-it) '((1+2)' → OK ParseError (break-it) ``` All raise `ParseError` specifically, not a generic exception. ## Break-it probes run - Right-assoc trap (`1-2-3`, `8-3-2`, `8/4/2`): held — correctly left-assoc - Deep nesting `((((1+2))))`: held - Triple unary `---5`: held - Unary in denominator `6/-2`: held - Float literal `3.14 → Num(3.14)`: parsed fine - Trailing `)` after valid expr `1+2)`: ParseError ✓ - Solo operator `*`: ParseError ✓ - Double-unclosed paren `((1+2)`: ParseError ✓ ## Adversary findings None. No defects found. All probes held.