artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
@ -0,0 +1,94 @@
|
||||
# STATUS-parse
|
||||
|
||||
## DONE
|
||||
|
||||
## Claimed gates: D1, D2, D3, D4, D5, D6
|
||||
|
||||
**Commit:** (see git log — latest push on main)
|
||||
**Files:** `calc/parser.py`, `calc/test_parser.py`
|
||||
|
||||
---
|
||||
|
||||
## AST Node Shapes
|
||||
|
||||
```
|
||||
Num(value) — numeric literal; value is int or float
|
||||
BinOp(op, left, right) — binary op; op in {'+', '-', '*', '/'}
|
||||
Unary(op, operand) — unary op; op is '-'
|
||||
```
|
||||
|
||||
All nodes are Python `dataclass` instances with `__eq__` and `__repr__`.
|
||||
|
||||
---
|
||||
|
||||
## Verify commands (run from repo root)
|
||||
|
||||
### D6 — all tests green
|
||||
```bash
|
||||
python -m unittest -q
|
||||
# Expected: Ran 33 tests in X.XXXs OK (14 lex + 19 parser)
|
||||
```
|
||||
|
||||
### D1 — `*` binds tighter than `+`
|
||||
```bash
|
||||
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)))
|
||||
```
|
||||
|
||||
### D2 — left associativity
|
||||
```bash
|
||||
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 override precedence
|
||||
```bash
|
||||
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
|
||||
```bash
|
||||
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 raise ParseError
|
||||
```bash
|
||||
python -c "
|
||||
from calc.lexer import tokenize
|
||||
from calc.parser import parse, ParseError
|
||||
cases = ['1 +', '(1', '1 2', ')(', '']
|
||||
for src in cases:
|
||||
try:
|
||||
parse(tokenize(src))
|
||||
print(f'FAIL {src!r}: no error raised')
|
||||
except ParseError as e:
|
||||
print(f'OK {src!r}: ParseError')
|
||||
except Exception as e:
|
||||
print(f'FAIL {src!r}: wrong exception {type(e).__name__}')
|
||||
"
|
||||
# Expected: OK for all 5 cases
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## DoD mapping
|
||||
|
||||
| Gate | DoD item | How verified |
|
||||
|------|----------|-------------|
|
||||
| D1 | `*`/`/` bind tighter than `+`/`-` | `1+2*3` → `BinOp('+', Num(1), BinOp('*', ...))` |
|
||||
| D2 | Same-precedence left-associative | `8-3-2` → left-nested; `8/4/2` → left-nested |
|
||||
| D3 | Parens override precedence | `(1+2)*3` → `BinOp('*', BinOp('+', ...), ...)` |
|
||||
| D4 | Unary minus (leading, nested, in mul) | `-5`, `-(1+2)`, `3 * -2` all parsed as Unary |
|
||||
| D5 | Malformed input raises ParseError | All 5 cases raise ParseError, not other exceptions |
|
||||
| D6 | 0 failures in `python -m unittest` | 33 tests OK (14 lex + 19 parser) |
|
||||
Reference in New Issue
Block a user