2.4 KiB
REVIEW — Phase lex (Adversary)
Verdicts
D1: PASS @2026-06-15T06:26:41Z
Cold run evidence:
NUMBER 42 int ✓ (integer, value==42, isinstance int)
NUMBER 3.14 float ✓
NUMBER 0.5 float ✓ (leading dot)
NUMBER 10.0 float ✓ (trailing dot)
Structure check: tokenize("42") → 2 tokens, [NUMBER(42), EOF]. Exact match.
Break-it probes: bare . raises ValueError (not LexError) — see Adversary finding AF-1 below. Not a DoD blocker (bare dot not in spec), logged as defect.
D2: PASS @2026-06-15T06:26:41Z
Cold run evidence:
tokenize("1+2*3") → ['NUMBER', 'PLUS', 'NUMBER', 'STAR', 'NUMBER', 'EOF'] ✓
tokenize("+-*/()") → ['PLUS','MINUS','STAR','SLASH','LPAREN','RPAREN','EOF'] ✓
All 6 operator/paren kinds verified.
D3: PASS @2026-06-15T06:26:41Z
Cold run evidence:
tokenize(" 12 + 3 ") → ['NUMBER', 'PLUS', 'NUMBER', 'EOF'] ✓
tokenize("1\t+\t2") → ['NUMBER', 'PLUS', 'NUMBER', 'EOF'] ✓
tokenize("1 @ 2") → calc.lexer.LexError: unexpected character '@' at position 2 ✓
tokenize("abc") → calc.lexer.LexError: unexpected character 'a' at position 0 ✓
tokenize("$") → calc.lexer.LexError: unexpected character '$' at position 0 ✓
LexError message contains offending char and its position.
D4: PASS @2026-06-15T06:26:41Z
Cold run evidence:
Ran 15 tests in 0.000s
OK
Plan's exact commands:
tokenize('3.5*(1-2)') → [('NUMBER', 3.5), ('STAR', '*'), ('LPAREN', '('), ('NUMBER', 1), ('MINUS', '-'), ('NUMBER', 2), ('RPAREN', ')'), ('EOF', '')] ✓
tokenize('1 @ 2') → calc.lexer.LexError: unexpected character '@' at position 2 ✓
Tests cover D1–D3 including all plan-required cases: " 12 + 3 ", "3.5*(1-2)", "1 @ 2".
Adversary Findings
AF-1 (non-blocking): bare . leaks ValueError instead of LexError
Repro: python -c "from calc.lexer import tokenize; tokenize('.')"
Actual: ValueError: could not convert string to float: '.'
Expected: LexError (or at minimum, not a raw ValueError from Python internals)
Impact: The DoD does not list bare dot as a required error case. Not blocking DONE, but future parser phases may hit this if they ever pass a stray . to the lexer. Recommend wrapping in a try/except and re-raising as LexError.
Status: OPEN (non-blocking)
No VETO
All DoD gates (D1, D2, D3, D4) verified PASS. Builder may write ## DONE to STATUS-lex.md.