2.4 KiB
STATUS-parse
Commit: 14d6662
AST Shape (contract for eval phase)
Num(value) — numeric literal; value is int or float
BinOp(op, left, right) — binary operation; op in ('+', '-', '*', '/')
Unary(op, operand) — unary minus; op == '-'
All nodes support __repr__ and __eq__. Import from calc.parser.
Gate Verification
D1 — precedence
What: * and / bind tighter than + and -
Command: 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)))
Observed:
BinOp('+', Num(1), BinOp('*', Num(2), Num(3)))
Result: PASS
D2 — left associativity
What: Same-precedence operators fold left: 8-3-2 → (8-3)-2; 8/4/2 → (8/4)/2
Command:
str(parse(tokenize('8-3-2'))) == "BinOp('-', BinOp('-', Num(8), Num(3)), Num(2))"
str(parse(tokenize('8/4/2'))) == "BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))"
Observed: Both assertions pass (confirmed via edge-case script) Result: PASS
D3 — parentheses
What: (1+2)*3 places + under *
Command:
str(parse(tokenize('(1+2)*3'))) == "BinOp('*', BinOp('+', Num(1), Num(2)), Num(3))"
Observed: Assertion passes (confirmed via edge-case script) Result: PASS
D4 — unary minus
What: -5, -(1+2), 3 * -2 all parse correctly
Commands:
str(parse(tokenize('-5'))) == "Unary('-', Num(5))"
str(parse(tokenize('-(1+2)'))) == "Unary('-', BinOp('+', Num(1), Num(2)))"
str(parse(tokenize('3 * -2'))) == "BinOp('*', Num(3), Unary('-', Num(2)))"
Observed: All three assertions pass (confirmed via edge-case script) Result: PASS
D5 — errors
What: "1 +", "(1", "1 2", ")(", "" each raise ParseError (not any other exception)
Command:
for bad in ['1 +', '(1', '1 2', ')(', '']:
try:
parse(tokenize(bad)); raise AssertionError(...)
except ParseError: pass
Observed: All five inputs raised ParseError; spot check of "1 +":
calc.parser.ParseError: unexpected end of expression
Result: PASS
D6 — tests green
What: python -m unittest -q passes, 0 failures, 37 tests total (14 lexer + 23 parser)
Command: python -m unittest -q
Observed:
Ran 37 tests in 0.001s
OK
Result: PASS