artifacts: add calculators/ — the 30 built calculators (5/variant) + machine-docs + git logs
This commit is contained in:
@ -0,0 +1,56 @@
|
||||
# JOURNAL — Phase parse (Builder)
|
||||
|
||||
## 2026-06-15 — Start
|
||||
|
||||
Reading phase plan. Lex phase is DONE. Building parser on top of `calc/lexer.py`.
|
||||
|
||||
### Design
|
||||
|
||||
Grammar (recursive descent):
|
||||
```
|
||||
expr → term (('+' | '-') term)*
|
||||
term → unary (('*' | '/') unary)*
|
||||
unary → '-' unary | primary
|
||||
primary → NUMBER | '(' expr ')'
|
||||
```
|
||||
|
||||
- `expr`/`term` loop = left-associative by construction
|
||||
- `term` deeper than `expr` = `*`/`/` higher precedence than `+`/`-`
|
||||
- `unary` recursive = right-associative unary (`--5` parses as `-(-5)`)
|
||||
|
||||
AST nodes:
|
||||
- `Num(value)` — leaf
|
||||
- `BinOp(op, left, right)` — binary operator
|
||||
- `Unary(op, operand)` — unary operator
|
||||
|
||||
ParseError raised for: empty string, trailing operator, unclosed paren, consecutive numbers, mismatched parens.
|
||||
|
||||
## 2026-06-15 — Implementation + tests run
|
||||
|
||||
```
|
||||
$ python -m unittest -q
|
||||
Ran 35 tests in 0.001s
|
||||
OK
|
||||
```
|
||||
(15 from test_lexer + 20 from test_parser)
|
||||
|
||||
Plan verify commands:
|
||||
```
|
||||
$ python -c "...parse(tokenize('1+2*3'))"
|
||||
BinOp('+', Num(1), BinOp('*', Num(2), Num(3))) # D1 ✓
|
||||
|
||||
$ python -c "...parse(tokenize('(1+2)*3'))"
|
||||
BinOp('*', BinOp('+', Num(1), Num(2)), Num(3)) # D3 ✓
|
||||
|
||||
$ python -c "...parse(tokenize('8-3-2'))"
|
||||
BinOp('-', BinOp('-', Num(8), Num(3)), Num(2)) # D2 ✓
|
||||
|
||||
$ python -c "...parse(tokenize('-5'))"
|
||||
Unary('-', Num(5)) # D4 ✓
|
||||
|
||||
$ python -c "...parse(tokenize('3 * -2'))"
|
||||
BinOp('*', Num(3), Unary('-', Num(2))) # D4 ✓
|
||||
|
||||
$ python -c "...parse(tokenize('1 +'))"
|
||||
calc.parser.ParseError: unexpected end of expression # D5 ✓
|
||||
```
|
||||
Reference in New Issue
Block a user