artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
@ -0,0 +1,120 @@
|
||||
# STATUS-parse
|
||||
|
||||
## DONE
|
||||
|
||||
## Claim
|
||||
|
||||
All DoD gates D1–D6 implemented and verified.
|
||||
|
||||
| Gate | Item | Status |
|
||||
|------|------|--------|
|
||||
| D1 | `*`/`/` bind tighter than `+`/`-` | claimed PASS |
|
||||
| D2 | Left associativity | claimed PASS |
|
||||
| D3 | Parentheses override precedence | claimed PASS |
|
||||
| D4 | Unary minus | claimed PASS |
|
||||
| D5 | ParseError on malformed input | claimed PASS |
|
||||
| D6 | `calc/test_parser.py` — 31 tests, 0 failures | claimed PASS |
|
||||
|
||||
## Files
|
||||
|
||||
- `calc/parser.py` — parser implementation
|
||||
- `calc/test_parser.py` — unittest suite
|
||||
|
||||
Commit: `00ca873` (claim(D1-D6): feat: add calc parser with AST nodes, recursive descent, full test suite)
|
||||
|
||||
## How to verify
|
||||
|
||||
```bash
|
||||
# D6 — all tests
|
||||
python -m unittest -q
|
||||
# Expected: OK (31 tests, 0 failures)
|
||||
|
||||
# D1 — mul binds tighter than add
|
||||
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 of subtraction
|
||||
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))
|
||||
|
||||
# D2 — left associativity of division
|
||||
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 with binary mul
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('3 * -2')))"
|
||||
# Expected: BinOp('*', Num(3), Unary('-', Num(2)))
|
||||
|
||||
# D4 — negation of group
|
||||
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-(1+2)')))"
|
||||
# Expected: Unary('-', BinOp('+', Num(1), Num(2)))
|
||||
|
||||
# D5 — ParseError on "1 +"
|
||||
python -c "
|
||||
from calc.lexer import tokenize
|
||||
from calc.parser import parse, ParseError
|
||||
try:
|
||||
parse(tokenize('1 +'))
|
||||
print('ERROR: no exception raised')
|
||||
except ParseError as e:
|
||||
print('OK ParseError:', e)
|
||||
"
|
||||
|
||||
# D5 — ParseError on "(1"
|
||||
python -c "
|
||||
from calc.lexer import tokenize
|
||||
from calc.parser import parse, ParseError
|
||||
try:
|
||||
parse(tokenize('(1'))
|
||||
print('ERROR: no exception raised')
|
||||
except ParseError as e:
|
||||
print('OK ParseError:', e)
|
||||
"
|
||||
|
||||
# D5 — ParseError on "1 2"
|
||||
python -c "
|
||||
from calc.lexer import tokenize
|
||||
from calc.parser import parse, ParseError
|
||||
try:
|
||||
parse(tokenize('1 2'))
|
||||
print('ERROR: no exception raised')
|
||||
except ParseError as e:
|
||||
print('OK ParseError:', e)
|
||||
"
|
||||
|
||||
# D5 — ParseError on ")("
|
||||
python -c "
|
||||
from calc.lexer import tokenize
|
||||
from calc.parser import parse, ParseError
|
||||
try:
|
||||
parse(tokenize(')('))
|
||||
print('ERROR: no exception raised')
|
||||
except ParseError as e:
|
||||
print('OK ParseError:', e)
|
||||
"
|
||||
|
||||
# D5 — ParseError on empty string
|
||||
python -c "
|
||||
from calc.lexer import tokenize
|
||||
from calc.parser import parse, ParseError
|
||||
try:
|
||||
parse(tokenize(''))
|
||||
print('ERROR: no exception raised')
|
||||
except ParseError as e:
|
||||
print('OK ParseError:', e)
|
||||
"
|
||||
```
|
||||
|
||||
## AST Node shapes
|
||||
|
||||
```
|
||||
Num(value) — leaf, value is int or float
|
||||
BinOp(op, left, right) — op is one of '+', '-', '*', '/'
|
||||
Unary(op, operand) — op is '-'
|
||||
```
|
||||
|
||||
All are dataclasses with `__repr__` that prints the form above.
|
||||
Reference in New Issue
Block a user