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

4.1 KiB
Raw Blame History

STATUS — phase parse

DONE

All gates D1D6 Adversary-verified PASS @2026-06-15T04:22:33Z. No vetoes. Phase complete.


Gates: D1D6 CLAIMED, awaiting Adversary

All six gates implemented and locally verified. Claiming all simultaneously.


AST node shapes (stable contract for evaluator)

  • Num(value) — leaf; value is int or float
  • BinOp(op, left, right) — binary op; op is 'PLUS'|'MINUS'|'STAR'|'SLASH'
  • Unary(op, operand) — unary minus; op is 'MINUS'

All nodes are frozen @dataclasss with __repr__ and __eq__ derived from fields. Defined in calc/parser.py.


D1 — precedence (CLAIMED)

WHAT: *// bind tighter than +/-: 1+2*3 parses as BinOp('PLUS', Num(1), BinOp('STAR', Num(2), Num(3))).

HOW:

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

EXPECTED:

BinOp('PLUS', Num(1), BinOp('STAR', Num(2), Num(3)))

WHERE: calc/parser.pyexpr() loops over +/-, term() loops over *//.


D2 — left associativity (CLAIMED)

WHAT: Same-precedence operators associate left.

  • 8-3-2BinOp('MINUS', BinOp('MINUS', Num(8), Num(3)), Num(2))
  • 8/4/2BinOp('SLASH', BinOp('SLASH', Num(8), Num(4)), Num(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('MINUS', BinOp('MINUS', Num(8), Num(3)), Num(2))
BinOp('SLASH', BinOp('SLASH', Num(8), Num(4)), Num(2))

WHERE: calc/parser.pywhile loops in expr() and term() fold left.


D3 — parentheses (CLAIMED)

WHAT: Parens override precedence: (1+2)*3BinOp('STAR', BinOp('PLUS', Num(1), Num(2)), Num(3)).

HOW:

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

EXPECTED:

BinOp('STAR', BinOp('PLUS', Num(1), Num(2)), Num(3))

WHERE: calc/parser.pyprimary() handles LPAREN … RPAREN.


D4 — unary minus (CLAIMED)

WHAT: Leading and nested unary minus works.

  • -5Unary('MINUS', Num(5))
  • -(1+2)Unary('MINUS', BinOp('PLUS', Num(1), Num(2)))
  • 3 * -2BinOp('STAR', Num(3), Unary('MINUS', Num(2)))

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('MINUS', Num(5))
Unary('MINUS', BinOp('PLUS', Num(1), Num(2)))
BinOp('STAR', Num(3), Unary('MINUS', Num(2)))

WHERE: calc/parser.pyunary() intercepts MINUS before primary().


D5 — errors (CLAIMED)

WHAT: Each malformed input raises ParseError (not any other exception).

HOW:

python -c "
from calc.lexer import tokenize
from calc.parser import parse, ParseError
cases = ['1 +', '(1', '1 2', ')(', '']
for src in cases:
    try:
        parse(tokenize(src))
        print('FAIL — no error for', repr(src))
    except ParseError as e:
        print('OK', repr(src), '->', e)
"

EXPECTED (all OK lines):

OK '1 +' -> unexpected token 'EOF'
OK '(1' -> expected ')', got 'EOF'
OK '1 2' -> unexpected token 'NUMBER' after expression
OK ')(' -> unexpected token 'RPAREN'
OK '' -> unexpected token 'EOF'

WHERE: calc/parser.pyprimary() raises on bad token; trailing-token check after expr().


D6 — tests green (CLAIMED)

WHAT: python -m unittest -q runs 39 tests (17 lex + 22 parser), 0 failures.

HOW:

python -m unittest -q

EXPECTED:

----------------------------------------------------------------------
Ran 39 tests in ...s

OK

WHERE: calc/test_parser.py — 22 tests across 5 classes (TestPrecedence, TestLeftAssociativity, TestParentheses, TestUnaryMinus, TestErrors).