# REVIEW-parse — Adversary Verdicts ## Gate Verdicts (cold-verified from work-adv clone, commit 79016f1) ### parse/D1: PASS @2026-06-15T01:15Z Cold run — precedence verified structurally: - `parse(tokenize('1+2*3'))` → `BinOp('+', Num(1), BinOp('*', Num(2), Num(3)))` ✓ (`*` deeper than `+`) - `parse(tokenize('2*3+1'))` → `BinOp('+', BinOp('*', Num(2), Num(3)), Num(1))` ✓ - `parse(tokenize('10-4/2'))` → `BinOp('-', Num(10), BinOp('/', Num(4), Num(2)))` ✓ - Extra: `1+2*3+4` → `BinOp('+', BinOp('+', Num(1), BinOp('*', Num(2), Num(3))), Num(4))` ✓ ### parse/D2: PASS @2026-06-15T01:15Z Cold run — left associativity verified structurally: - `parse(tokenize('8-3-2'))` → `BinOp('-', BinOp('-', Num(8), Num(3)), Num(2))` ✓ (first `-` is left child) - `parse(tokenize('8/4/2'))` → `BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))` ✓ - Extra: `1+2+3` → `BinOp('+', BinOp('+', Num(1), Num(2)), Num(3))` ✓ ### parse/D3: PASS @2026-06-15T01:15Z Cold run — parens override precedence: - `parse(tokenize('(1+2)*3'))` → `BinOp('*', BinOp('+', Num(1), Num(2)), Num(3))` ✓ (`+` deeper than `*`) - Extra nested: `((((1))))` → `Num(1)` ✓ - Extra mixed: `2*(3+4*5)` → `BinOp('*', Num(2), BinOp('+', Num(3), BinOp('*', Num(4), Num(5))))` ✓ ### parse/D4: PASS @2026-06-15T01:15Z Cold run — unary minus: - `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: `--5` → `Unary('-', Unary('-', Num(5)))` ✓ (right-recursive unary) - Extra: `-1+-2` → `BinOp('+', Unary('-', Num(1)), Unary('-', Num(2)))` ✓ - Extra: `-3*2` → `BinOp('*', Unary('-', Num(3)), Num(2))` ✓ (unary higher-prec than `*`) - Extra: `3--2` → `BinOp('-', Num(3), Unary('-', Num(2)))` ✓ ### parse/D5: PASS @2026-06-15T01:15Z Cold run — all 5 plan-mandated cases raise `ParseError` (not any other exception type): - `"1 +"` → `ParseError: unexpected end of input` ✓ - `"(1"` → `ParseError: unclosed parenthesis, expected ')'` ✓ - `"1 2"` → `ParseError: unexpected token 'NUMBER'` ✓ - `")("` → `ParseError: unexpected token 'RPAREN'` ✓ - `""` → `ParseError: empty expression` ✓ Extra adversarial cases also raise `ParseError` correctly: - `"*2"`, `"/2"`, `"()"`, `"1+"`, `"1/"` — all `ParseError` ✓ ### parse/D6: PASS @2026-06-15T01:15Z ``` $ python -m unittest -q ............................................ Ran 44 tests in 0.001s OK ``` 44 tests (18 lexer + 26 parser), 0 failures, exit 0 ✓ Tests assert structural equality using dataclass `__eq__` — not weak string comparison. Covers all D1-D5 cases including boundary and combinatorial inputs. ## Adversary Findings No findings. Implementation is clean. - `ParseError` is a proper subclass of `Exception` (not `SyntaxError` or other built-in) ✓ - AST nodes use operator symbols (`'+'`, `'-'`, etc.) not token kind names ✓ - Stable documented shape: `Num(value)`, `BinOp(op, left, right)`, `Unary(op, operand)` ✓ ## Summary All six gates D1–D6 verified PASS from cold start in work-adv clone at commit 79016f1.