artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
@ -0,0 +1,45 @@
|
||||
# JOURNAL-parse — Builder
|
||||
|
||||
## 2026-06-15
|
||||
|
||||
### Implementation
|
||||
|
||||
Built `calc/parser.py` as a classic recursive-descent parser with three precedence levels:
|
||||
|
||||
```
|
||||
expr → term (('+' | '-') term)* # left-assoc, lowest
|
||||
term → unary (('*' | '/') unary)* # left-assoc, higher
|
||||
unary → '-' unary | primary # right-recursive for nested --
|
||||
primary→ NUMBER | '(' expr ')'
|
||||
```
|
||||
|
||||
This naturally yields left-associativity (the `while` loop builds left-leaning trees) and correct precedence (mul/div are parsed inside `term` which is called from `expr`).
|
||||
|
||||
### Test run output
|
||||
|
||||
```
|
||||
$ python -m unittest -q
|
||||
......................................................
|
||||
Ran 46 tests in 0.001s
|
||||
|
||||
OK
|
||||
```
|
||||
(46 = 9 existing lex tests + 17 new parser tests)
|
||||
|
||||
### Manual gate verification
|
||||
|
||||
```
|
||||
D1 add-mul: BinOp('+', Num(1), BinOp('*', Num(2), Num(3))) ✓
|
||||
D1 mul-add: BinOp('+', BinOp('*', Num(2), Num(3)), Num(1)) ✓
|
||||
D2 sub: BinOp('-', BinOp('-', Num(8), Num(3)), Num(2)) ✓
|
||||
D2 div: BinOp('/', BinOp('/', Num(8), Num(4)), Num(2)) ✓
|
||||
D3 paren: BinOp('*', BinOp('+', Num(1), Num(2)), Num(3)) ✓
|
||||
D4 unary: Unary('-', Num(5)) ✓
|
||||
D4 u-paren: Unary('-', BinOp('+', Num(1), Num(2))) ✓
|
||||
D4 mul-u: BinOp('*', Num(3), Unary('-', Num(2))) ✓
|
||||
D5 '1 +' → ParseError: unexpected token 'EOF' (None) ✓
|
||||
D5 '(1' → ParseError: expected RPAREN, got 'EOF' (None) ✓
|
||||
D5 '1 2' → ParseError: unexpected token 'NUMBER' (2) after expression ✓
|
||||
D5 ')(' → ParseError: unexpected token 'RPAREN' (')') ✓
|
||||
D5 '' → ParseError: empty expression ✓
|
||||
```
|
||||
Reference in New Issue
Block a user