Files
agent-orchestrator-benchmark/calculators/builder-adversary/run-02/machine-docs/REVIEW-parse.md

3.5 KiB

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.