2.3 KiB
2.3 KiB
REVIEW — phase parse
Verdict
review(D1-D6): PASS — all six gates verified cold at a05812d
D1: PASS @2026-06-15T02:10Z
Precedence correct: *// bind tighter than +/- via two-level grammar (expr → _term → _unary → _primary).
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)) ✓
parse(tokenize('9-4/2')) => BinOp('-', Num(9), BinOp('/', Num(4), Num(2))) ✓
D2: PASS @2026-06-15T02:10Z
Left associativity correct: while-loops in expr() and _term() accumulate left-to-right.
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)) ✓
parse(tokenize('1+2+3')) => BinOp('+', BinOp('+', Num(1), Num(2)), Num(3)) ✓
D3: PASS @2026-06-15T02:10Z
Parentheses override precedence via _primary() grouping.
parse(tokenize('(1+2)*3')) => BinOp('*', BinOp('+', Num(1), Num(2)), Num(3)) ✓
parse(tokenize('((2+3))')) => BinOp('+', Num(2), Num(3)) ✓
D4: PASS @2026-06-15T02:10Z
Unary minus handled at _unary(), right-recursive, correct for all cases including nested and post-operator.
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))) ✓
parse(tokenize('--5')) => Unary('-', Unary('-', Num(5))) ✓
parse(tokenize('---5')) => Unary('-', Unary('-', Unary('-', Num(5)))) ✓
parse(tokenize('-(1+2)*3')) => BinOp('*', Unary('-', BinOp('+', Num(1), Num(2))), Num(3)) ✓
D5: PASS @2026-06-15T02:10Z
All five required error cases raise ParseError (not any other exception). Adversarial extras also raise correctly.
'1 +' => ParseError ✓
'(1' => ParseError ✓
'1 2' => ParseError ✓
')(' => ParseError ✓
'' => ParseError ✓
# additional probes:
'*5' => ParseError ✓
'()' => ParseError ✓
'+' => ParseError ✓
'1+2)' => ParseError ✓
D6: PASS @2026-06-15T02:10Z
python -m unittest -q → 30 tests, 0 failures, 0 errors.
Gates to verify: D1 D2 D3 D4 D5 D6 — all PASS.