# REVIEW-parse — Adversary Verdicts ## Legend - PASS @ — gate accepted, evidence below - FAIL — repro steps below, Builder must fix --- ## D1 — precedence **PASS @2026-06-15T00:50Z** Cold run evidence: ``` parse(tokenize('1+2*3')) → BinOp('+', Num(1), BinOp('*', Num(2), Num(3))) ✓ parse(tokenize('2*3+1')) → BinOp('+', BinOp('*', Num(2), Num(3)), Num(1)) ✓ ``` Both match expected repr exactly. `*` binds tighter than `+` in both orderings. Extra probe — complex chain `1+2+3*4-5`: → `BinOp('-', BinOp('+', BinOp('+', Num(1), Num(2)), BinOp('*', Num(3), Num(4))), Num(5))` ✓ `3*4` is correctly nested under addition/subtraction. --- ## D2 — left associativity **PASS @2026-06-15T00:50Z** Cold run evidence: ``` parse(tokenize('8-3-2')) → BinOp('-', BinOp('-', Num(8), Num(3)), Num(2)) ✓ parse(tokenize('8/4/2')) → BinOp('/', BinOp('/', Num(8), Num(4)), Num(2)) ✓ ``` Extra probes: ``` parse(tokenize('2*3*4')) → BinOp('*', BinOp('*', Num(2), Num(3)), Num(4)) ✓ parse(tokenize('1+2+3')) → BinOp('+', BinOp('+', Num(1), Num(2)), Num(3)) ✓ ``` Explicit assertion `r == BinOp('+', BinOp('+', Num(1), Num(2)), Num(3))` passed. --- ## D3 — parentheses **PASS @2026-06-15T00:50Z** Cold run evidence: ``` parse(tokenize('(1+2)*3')) → BinOp('*', BinOp('+', Num(1), Num(2)), Num(3)) ✓ parse(tokenize('(-3)*2')) → BinOp('*', Unary('-', Num(3)), Num(2)) ✓ ``` Parens correctly place `+` sub-tree under `*`. --- ## D4 — unary minus **PASS @2026-06-15T00:50Z** Cold run evidence: ``` parse(tokenize('-5')) → Unary('-', Num(5)) ✓ parse(tokenize('-(1+2)')) → Unary('-', BinOp('+', Num(1), Num(2))) ✓ parse(tokenize('3 * -2')) → BinOp('*', Num(3), Unary('-', Num(2))) ✓ ``` Extra probes: ``` parse(tokenize('--5')) → Unary('-', Unary('-', Num(5))) ✓ (recursive, correct) parse(tokenize('(-3)*2')) → BinOp('*', Unary('-', Num(3)), Num(2)) ✓ ``` `_unary` is correctly recursive for double-negation. --- ## D5 — errors **PASS @2026-06-15T00:50Z** Cold run — all five DoD-mandated cases: ``` '1 +' → ParseError: unexpected token 'EOF' (None) ✓ '(1' → ParseError: expected RPAREN, got 'EOF' (None) ✓ '1 2' → ParseError: unexpected token 'NUMBER' (2) after expression ✓ ')(' → ParseError: unexpected token 'RPAREN' (')') ✓ '' → ParseError: empty expression ✓ ``` All raise `ParseError` (not `ValueError`, `IndexError`, or other exceptions). Extra break-it probes — all raise `ParseError` (not other exceptions): ``` '+5' → ParseError: unexpected token 'PLUS' ('+') ✓ '1++2' → ParseError: unexpected token 'PLUS' ('+') ✓ '()' → ParseError: unexpected token 'RPAREN' (')') ✓ '1 /' → ParseError: unexpected token 'EOF' (None) ✓ '* 2' → ParseError: unexpected token 'STAR' ('*') ✓ ``` --- ## D6 — tests green **PASS @2026-06-15T00:50Z** Cold run: ``` $ python -m unittest -q ---------------------------------------------------------------------- Ran 46 tests in 0.001s OK ``` Exit code 0. 46/46 pass (24 lex + 22 parser). DoD requires 0 failures — confirmed. --- ## Summary | Gate | Verdict | |------|---------| | D1 — precedence | **PASS** | | D2 — left associativity | **PASS** | | D3 — parentheses | **PASS** | | D4 — unary minus | **PASS** | | D5 — errors | **PASS** | | D6 — tests green | **PASS** | All gates PASS. No findings. Builder may write "## DONE" to STATUS-parse.md.