3.0 KiB
REVIEW — phase parse (Adversary)
Verdicts
| Gate | Verdict | Timestamp |
|---|---|---|
| D1 | PASS | 2026-06-15T02:42Z |
| D2 | PASS | 2026-06-15T02:42Z |
| D3 | PASS | 2026-06-15T02:42Z |
| D4 | PASS | 2026-06-15T02:42Z |
| D5 | PASS | 2026-06-15T02:42Z |
| D6 | PASS | 2026-06-15T02:42Z |
D1: PASS @2026-06-15T02:42Z
*// bind tighter than +/-. Cold-run:
1+2*3 → BinOp('+', Num(1), BinOp('*', Num(2), Num(3))) ✓
2*3+4 → BinOp('+', BinOp('*', Num(2), Num(3)), Num(4)) ✓
10-6/2 → BinOp('-', Num(10), BinOp('/', Num(6), Num(2))) ✓
Grammar verified: _expr calls _term (which handles *//) before combining with +/- — precedence is structurally encoded, not a test artifact.
D2: PASS @2026-06-15T02:42Z
Left-associativity for all four operators. Cold-run:
8-3-2 → BinOp('-', BinOp('-', Num(8), Num(3)), Num(2)) ✓
8/4/2 → BinOp('/', BinOp('/', Num(8), Num(4)), Num(2)) ✓
1+2+3 → BinOp('+', BinOp('+', Num(1), Num(2)), Num(3)) ✓
Associativity comes from while loops in _expr/_term that accumulate left into node — correct by construction.
D3: PASS @2026-06-15T02:42Z
Parentheses override precedence. Cold-run:
(1+2)*3 → BinOp('*', BinOp('+', Num(1), Num(2)), Num(3)) ✓
((4)) → Num(4) ✓
2*(3+4) → BinOp('*', Num(2), BinOp('+', Num(3), Num(4))) ✓
D4: PASS @2026-06-15T02:42Z
Unary minus: leading, nested, after binary operator, double negation. Cold-run:
-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))) ✓
Adversarial: ---5 → Unary('-', Unary('-', Unary('-', Num(5)))) ✓, (-5)*3 → BinOp('*', Unary('-', Num(5)), Num(3)) ✓.
D5: PASS @2026-06-15T02:42Z
All five plan-specified error cases raise ParseError (not a bare crash). Cold-run:
"1 +" → ParseError: unexpected token 'EOF' (None) ✓
"(1" → ParseError: expected 'RPAREN', got 'EOF' ✓
"1 2" → ParseError: unexpected token 'NUMBER' (2) ✓
")(" → ParseError: unexpected token 'RPAREN' (')') ✓
"" → ParseError: empty input ✓
Additional adversarial: +5, 1*), *5 all raise ParseError ✓.
D6: PASS @2026-06-15T02:42Z
python -m unittest -q
Ran 31 tests in 0.001s
OK
Tests assert on tree structure (dataclass equality), not on evaluation — correct testing approach per plan.
Notes
Grammar is clean recursive descent:
expr → term (('+' | '-') term)*term → unary (('*' | '/') unary)*unary → '-' unary | primaryprimary → NUMBER | '(' expr ')'
Precedence and associativity are structurally encoded, not patched in. No weak tests that would pass a wrong implementation found.