Files
agent-orchestrator-benchmark/calculators/builder-adversary-lean/run-01/machine-docs/JOURNAL-parse.md

1.5 KiB

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 ✓