# STATUS-parse.md — Builder status ## DONE ## Current state All gates D1–D6 verified PASS by Adversary @2026-06-15T01:24Z. Phase complete. ## What was built - `calc/parser.py` — recursive-descent parser exposing `parse(tokens) -> Node` - `calc/test_parser.py` — 27 unittest tests covering D1–D5 structure assertions ## AST node shapes (stable contract for evaluator) ```python @dataclass class Num: value: Union[int, float] # leaf @dataclass class BinOp: op: str # '+', '-', '*', '/' left: Node right: Node @dataclass class Unary: op: str # '-' operand: Node ``` ## Exact verification commands (re-run from any clone) ### D1 — precedence ``` python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('1+2*3')))" ``` **Expected:** `BinOp('+', Num(1), BinOp('*', Num(2), Num(3)))` ``` python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('2*3+1')))" ``` **Expected:** `BinOp('+', BinOp('*', Num(2), Num(3)), Num(1))` ### D2 — left associativity ``` python -c "from calc.lexer import tokenize; from calc.parser import parse; print(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(parse(tokenize('8/4/2')))" ``` **Expected:** `BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))` ### D3 — parentheses ``` python -c "from calc.lexer import tokenize; from calc.parser import parse; print(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(parse(tokenize('-5')))" ``` **Expected:** `Unary('-', Num(5))` ``` python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-(1+2)')))" ``` **Expected:** `Unary('-', BinOp('+', Num(1), Num(2)))` ``` python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('3 * -2')))" ``` **Expected:** `BinOp('*', Num(3), Unary('-', Num(2)))` ### D5 — errors (each must raise ParseError, not any other exception) ``` python -c "from calc.lexer import tokenize; from calc.parser import parse, ParseError for expr in ['1 +', '(1', '1 2', ')(', '']: try: parse(tokenize(expr)) print(f'FAIL {expr!r}: no error raised') except ParseError as e: print(f'OK {expr!r}: ParseError: {e}') except Exception as e: print(f'FAIL {expr!r}: wrong exception {type(e).__name__}: {e}') " ``` **Expected output:** 5 lines all starting with `OK`. ### D6 — tests green ``` python -m unittest -q ``` **Expected:** `Ran 43 tests in 0.00Xs` `OK` (16 lexer + 27 parser, 0 failures) ## Commit All source in latest push on main. `calc/parser.py` and `calc/test_parser.py` are the relevant files.