artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
@ -0,0 +1,46 @@
|
||||
# JOURNAL — phase: parse (Builder)
|
||||
|
||||
## 2026-06-15
|
||||
|
||||
### Design decisions
|
||||
|
||||
Chose a classic recursive-descent parser with separate grammar levels for precedence:
|
||||
|
||||
- `_expr` handles `+`/`-` (low precedence, left-associative via while-loop)
|
||||
- `_term` handles `*`/`/` (high precedence, left-associative via while-loop)
|
||||
- `_unary` handles prefix `-` (right-associative via recursion)
|
||||
- `_primary` handles `NUMBER` and `(expr)`
|
||||
|
||||
Left-associativity comes naturally from the iterative loop pattern (each iteration wraps the accumulating `left` node deeper).
|
||||
|
||||
### Verification runs
|
||||
|
||||
```
|
||||
$ python -m unittest -q
|
||||
Ran 41 tests in 0.001s
|
||||
OK
|
||||
```
|
||||
|
||||
Key shape outputs verified:
|
||||
```
|
||||
1+2*3 → BinOp(PLUS, Num(1), BinOp(STAR, Num(2), Num(3))) ✓ D1
|
||||
8-3-2 → BinOp(MINUS, BinOp(MINUS, Num(8), Num(3)), Num(2)) ✓ D2
|
||||
8/4/2 → BinOp(SLASH, BinOp(SLASH, Num(8), Num(4)), Num(2)) ✓ D2
|
||||
(1+2)*3 → BinOp(STAR, BinOp(PLUS, Num(1), Num(2)), Num(3)) ✓ D3
|
||||
-5 → Unary(MINUS, Num(5)) ✓ D4
|
||||
-(1+2) → Unary(MINUS, BinOp(PLUS, Num(1), Num(2))) ✓ D4
|
||||
3*-2 → BinOp(STAR, Num(3), Unary(MINUS, Num(2))) ✓ D4
|
||||
```
|
||||
|
||||
D5 errors all raise `ParseError` (not `SyntaxError`, `ValueError`, etc.):
|
||||
- `"1 +"` → ParseError: unexpected token 'EOF'
|
||||
- `"(1"` → ParseError: expected ')', got 'EOF'
|
||||
- `"1 2"` → ParseError: unexpected token 'NUMBER' after expression
|
||||
- `")("` → ParseError: unexpected token 'RPAREN'
|
||||
- `""` → ParseError: empty input
|
||||
|
||||
### Empty-string handling
|
||||
|
||||
`tokenize('')` returns `[Token('EOF')]`. The `parse()` function checks the first token;
|
||||
if it's `EOF`, raises `ParseError("empty input")` immediately, avoiding an ambiguous
|
||||
"unexpected token 'EOF'" message.
|
||||
Reference in New Issue
Block a user