Files
agent-orchestrator-benchmark/calculators/builder-adversary-stateless/run-03/machine-docs/STATUS-parse.md

3.4 KiB
Raw Blame History

STATUS — Phase parse (Builder)

DONE

All gates D1D6: Adversary-verified PASS (see REVIEW-parse.md @2026-06-15T04:08Z). Phase complete.

AST Node Shapes (stable API for evaluator)

Num(value)               # numeric literal; value is int or float
BinOp(op, left, right)   # op in {'+', '-', '*', '/'}; left/right are nodes
Unary(op, operand)       # op is '-'; operand is a node

All nodes implement __repr__ and __eq__.

Gate Claims

D1 — Precedence

WHAT: * and / bind tighter than + and -; 1+2*3 parses as 1+(2*3).
HOW:

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)))
WHERE: calc/parser.py_expr iterates +/-, _term iterates *//, so * folds first.

D2 — Left Associativity

WHAT: 8-3-2 parses as (8-3)-2; 8/4/2 as (8/4)/2.
HOW:

python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('8-3-2')))"
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('8/4/2')))"

EXPECTED:

  • BinOp('-', BinOp('-', Num(8), Num(3)), Num(2))
  • BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))
    WHERE: calc/parser.py_expr and _term use while loops (iterative left fold).

D3 — Parentheses

WHAT: (1+2)*3 parses with + under *.
HOW:

python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('(1+2)*3')))"

EXPECTED: BinOp('*', BinOp('+', Num(1), Num(2)), Num(3))
WHERE: calc/parser.py_primary handles LPAREN expr RPAREN, returning inner node to be used in _term.

D4 — Unary Minus

WHAT: -5, -(1+2), 3 * -2 each parse correctly.
HOW:

python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-5')))"
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-(1+2)')))"
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('3 * -2')))"

EXPECTED:

  • Unary('-', Num(5))
  • Unary('-', BinOp('+', Num(1), Num(2)))
  • BinOp('*', Num(3), Unary('-', Num(2)))
    WHERE: calc/parser.py_unary handles MINUS recursively before _primary.

D5 — Errors

WHAT: Malformed inputs raise ParseError (not any other exception).
HOW:

python -c "from calc.lexer import tokenize; from calc.parser import parse, ParseError
try:
    parse(tokenize('1 +'))
    print('NO ERROR')
except ParseError:
    print('ParseError OK')
"
# Repeat for each case: '(1', '1 2', ')(', ''

EXPECTED: ParseError raised for all five inputs: "1 +", "(1", "1 2", ")(", "".
Shortcut — test suite already covers all five (TestErrors class).
WHERE: calc/parser.py_primary raises on bad token; parse() raises on trailing token or empty input; _expect raises on mismatched RPAREN.

D6 — Tests Green

WHAT: python -m unittest -q passes, 0 failures; covers D1D5 with structural assertions.
HOW:

python -m unittest -q

EXPECTED: Ran 44 tests in ...s\n\nOK (21 lexer + 23 parser)
WHERE: calc/test_parser.py — classes TestPrecedence, TestLeftAssociativity, TestParentheses, TestUnaryMinus, TestErrors.