# STATUS — phase: parse (Builder) ## DONE ## Gate: D1–D6 — ALL PASS (Adversary-verified @2026-06-15T01:42:00Z) ### WHAT is claimed All six gates D1–D6 are implemented and tested. - **D1 (precedence):** `*`/`/` bind tighter than `+`/`-` - **D2 (left associativity):** Same-precedence ops associate left - **D3 (parentheses):** Parens override precedence - **D4 (unary minus):** Leading and nested unary minus - **D5 (errors):** Five malformed inputs each raise `ParseError` - **D6 (tests green):** 19 parser tests + 22 lexer tests = 41 total, 0 failures ### HOW to verify (run from a fresh clone) **D6 — all tests green:** ```bash python -m unittest -q ``` Expected output: `Ran 41 tests in 0.00xs` / `OK` **D1 — precedence (structural check):** ```bash python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('1+2*3')))" ``` Expected: `BinOp(PLUS, Num(1), BinOp(STAR, Num(2), Num(3)))` ```bash python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('6-4/2')))" ``` Expected: `BinOp(MINUS, Num(6), BinOp(SLASH, Num(4), Num(2)))` **D2 — left associativity:** ```bash python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('8-3-2')))" ``` Expected: `BinOp(MINUS, BinOp(MINUS, Num(8), Num(3)), Num(2))` ```bash python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('8/4/2')))" ``` Expected: `BinOp(SLASH, BinOp(SLASH, Num(8), Num(4)), Num(2))` **D3 — parentheses:** ```bash python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('(1+2)*3')))" ``` Expected: `BinOp(STAR, BinOp(PLUS, Num(1), Num(2)), Num(3))` **D4 — unary minus:** ```bash python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-5')))" ``` Expected: `Unary(MINUS, Num(5))` ```bash python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-(1+2)')))" ``` Expected: `Unary(MINUS, BinOp(PLUS, Num(1), Num(2)))` ```bash python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('3 * -2')))" ``` Expected: `BinOp(STAR, Num(3), Unary(MINUS, Num(2)))` **D5 — errors (each must raise `ParseError`, not a different exception):** ```bash python -c "from calc.lexer import tokenize; from calc.parser import parse; parse(tokenize('1 +'))" # raises: ParseError: unexpected token 'EOF' python -c "from calc.lexer import tokenize; from calc.parser import parse; parse(tokenize('(1'))" # raises: ParseError: expected ')', got 'EOF' python -c "from calc.lexer import tokenize; from calc.parser import parse; parse(tokenize('1 2'))" # raises: ParseError: unexpected token 'NUMBER' after expression python -c "from calc.lexer import tokenize; from calc.parser import parse; parse(tokenize(')('))" # raises: ParseError: unexpected token 'RPAREN' python -c "from calc.lexer import tokenize; from calc.parser import parse; parse(tokenize(''))" # raises: ParseError: empty input ``` ### EXPECTED AST shapes (re-derivable from grammar) AST node types: - `Num(value)` — numeric literal; value is int or float - `BinOp(op, left, right)` — op in `{'PLUS','MINUS','STAR','SLASH'}` - `Unary(op, operand)` — op == `'MINUS'` Grammar used (drives precedence + associativity): ``` expr : term (('+' | '-') term)* ← left-assoc, low precedence term : unary (('*' | '/') unary)* ← left-assoc, high precedence unary : '-' unary | primary ← right-assoc chain, prefix only primary : NUMBER | '(' expr ')' ``` ### WHERE (commit sha) `23d0ae9` (claim(D1,D2,D3,D4,D5,D6): parser complete, all 41 tests green) ### Files - `calc/parser.py` — ParseError, Num, BinOp, Unary, _Parser, parse() - `calc/test_parser.py` — 19 unittest cases covering D1–D5 ### Gate checklist - D1 (precedence): CLAIMED - D2 (left associativity): CLAIMED - D3 (parentheses): CLAIMED - D4 (unary minus): CLAIMED - D5 (errors): CLAIMED - D6 (tests green): CLAIMED