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

3.4 KiB
Raw Blame History

STATUS-parse

DONE

Claim

All DoD gates D1D6 implemented and verified.

Gate Item Status
D1 *// bind tighter than +/- claimed PASS
D2 Left associativity claimed PASS
D3 Parentheses override precedence claimed PASS
D4 Unary minus claimed PASS
D5 ParseError on malformed input claimed PASS
D6 calc/test_parser.py — 31 tests, 0 failures claimed PASS

Files

  • calc/parser.py — parser implementation
  • calc/test_parser.py — unittest suite

Commit: 00ca873 (claim(D1-D6): feat: add calc parser with AST nodes, recursive descent, full test suite)

How to verify

# D6 — all tests
python -m unittest -q
# Expected: OK (31 tests, 0 failures)

# D1 — mul binds tighter than add
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)))

# D2 — left associativity of subtraction
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('8-3-2')))"
# Expected: BinOp('-', BinOp('-', Num(8), Num(3)), Num(2))

# D2 — left associativity of division
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('8/4/2')))"
# Expected: BinOp('/', BinOp('/', Num(8), Num(4)), Num(2))

# D3 — parens override precedence
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))

# D4 — unary minus with binary mul
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('3 * -2')))"
# Expected: BinOp('*', Num(3), Unary('-', Num(2)))

# D4 — negation of group
python -c "from calc.lexer import tokenize; from calc.parser import parse; print(parse(tokenize('-(1+2)')))"
# Expected: Unary('-', BinOp('+', Num(1), Num(2)))

# D5 — ParseError on "1 +"
python -c "
from calc.lexer import tokenize
from calc.parser import parse, ParseError
try:
    parse(tokenize('1 +'))
    print('ERROR: no exception raised')
except ParseError as e:
    print('OK ParseError:', e)
"

# D5 — ParseError on "(1"
python -c "
from calc.lexer import tokenize
from calc.parser import parse, ParseError
try:
    parse(tokenize('(1'))
    print('ERROR: no exception raised')
except ParseError as e:
    print('OK ParseError:', e)
"

# D5 — ParseError on "1 2"
python -c "
from calc.lexer import tokenize
from calc.parser import parse, ParseError
try:
    parse(tokenize('1 2'))
    print('ERROR: no exception raised')
except ParseError as e:
    print('OK ParseError:', e)
"

# D5 — ParseError on ")("
python -c "
from calc.lexer import tokenize
from calc.parser import parse, ParseError
try:
    parse(tokenize(')('))
    print('ERROR: no exception raised')
except ParseError as e:
    print('OK ParseError:', e)
"

# D5 — ParseError on empty string
python -c "
from calc.lexer import tokenize
from calc.parser import parse, ParseError
try:
    parse(tokenize(''))
    print('ERROR: no exception raised')
except ParseError as e:
    print('OK ParseError:', e)
"

AST Node shapes

Num(value)              — leaf, value is int or float
BinOp(op, left, right)  — op is one of '+', '-', '*', '/'
Unary(op, operand)      — op is '-'

All are dataclasses with __repr__ that prints the form above.