artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
@ -0,0 +1,70 @@
|
||||
## DONE
|
||||
|
||||
# STATUS — phase `parse`
|
||||
|
||||
## Claimed gates: D1 D2 D3 D4 D5 D6
|
||||
|
||||
## Files
|
||||
- `calc/parser.py` — parser implementation
|
||||
- `calc/test_parser.py` — unittest suite
|
||||
|
||||
## AST node shapes
|
||||
|
||||
```
|
||||
Num(value) — leaf numeric literal; value is int or float
|
||||
BinOp(op, left, right) — binary op; op is one of '+' '-' '*' '/'
|
||||
Unary(op, operand) — unary op; op is '-'
|
||||
```
|
||||
|
||||
All nodes implement `__repr__` and `__eq__`.
|
||||
|
||||
## How to verify
|
||||
|
||||
```bash
|
||||
# D6 — all tests green
|
||||
python -m unittest -q
|
||||
|
||||
# D1 — * binds tighter than +
|
||||
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
|
||||
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 — parens override precedence
|
||||
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 — ParseError for malformed input
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse, ParseError
|
||||
for s in ['1 +', '(1', '1 2', ')(' , '']:
|
||||
try:
|
||||
parse(tokenize(s))
|
||||
print('FAIL', s)
|
||||
except ParseError:
|
||||
print('OK', repr(s))
|
||||
"
|
||||
# expected: all 5 lines print OK
|
||||
|
||||
# D1/D3 anti-confusion check — structure differs:
|
||||
# 1+2*3 => BinOp('+', Num(1), BinOp('*', Num(2), Num(3))) [* is the right child of +]
|
||||
# (1+2)*3 => BinOp('*', BinOp('+', Num(1), Num(2)), Num(3)) [+ is the left child of *]
|
||||
```
|
||||
|
||||
## Commit
|
||||
|
||||
`a05812d` — claim(D1-D6): add recursive-descent parser with full gate coverage
|
||||
Reference in New Issue
Block a user