# STATUS — Phase `parse` ## DONE Gate: D1,D2,D3,D4,D5,D6 — all PASS (Adversary-verified @2026-06-15T04:03Z, commit e9a5152) ## What is claimed All DoD gates D1–D6 implemented and all 20 parser tests pass (34 total across lex+parse). **Commit:** see `claim(D1–D6)` commit on main. ## How to verify (cold, from a fresh clone) ```bash cd python -m unittest -q # Expect: Ran 34 tests in ~0.001s — OK # D1 — precedence (*/ tighter than +-) python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('1+2*3'))))" # Expected: BinOp('+', Num(1), BinOp('*', Num(2), Num(3))) # D2 — left associativity python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('8-3-2'))))" # Expected: BinOp('-', BinOp('-', Num(8), Num(3)), Num(2)) python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('8/4/2'))))" # Expected: BinOp('/', BinOp('/', Num(8), Num(4)), Num(2)) # D3 — parentheses override python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('(1+2)*3'))))" # Expected: BinOp('*', BinOp('+', Num(1), Num(2)), Num(3)) # D4 — unary minus python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('-5'))))" # Expected: Unary('-', Num(5)) python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('-(1+2)'))))" # Expected: Unary('-', BinOp('+', Num(1), Num(2))) python -c "from calc.lexer import tokenize; from calc.parser import parse; print(repr(parse(tokenize('3 * -2'))))" # Expected: BinOp('*', Num(3), Unary('-', Num(2))) # D5 — errors raise ParseError python -c "from calc.lexer import tokenize; from calc.parser import parse, ParseError for src in ['1 +', '(1', '1 2', ')(', '']: try: parse(tokenize(src)) print(f'FAIL: {src!r} did not raise') except ParseError as e: print(f'OK ParseError: {src!r}') " ``` ## Expected outputs - `python -m unittest -q` → `Ran 34 tests in ...s\nOK` - `1+2*3` → `BinOp('+', Num(1), BinOp('*', Num(2), Num(3)))` - `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))` - `-5` → `Unary('-', Num(5))` - `-(1+2)` → `Unary('-', BinOp('+', Num(1), Num(2)))` - `3 * -2` → `BinOp('*', Num(3), Unary('-', Num(2)))` - All 5 malformed inputs → `OK ParseError` ## AST shape (for evaluator) ``` Num(value) — numeric literal; value is int or float BinOp(op, left, right) — binary; op in {'+', '-', '*', '/'} Unary(op, operand) — unary minus; op == '-' ``` All three are `@dataclass`, so `==` comparison works for tests. ## Where - `calc/parser.py` — parser implementation - `calc/test_parser.py` — 20 parser tests covering D1–D5