# JOURNAL-parse ## Design decisions - **Grammar**: classic 3-level recursive descent: - `expr → term (('+' | '-') term)*` (lowest precedence) - `term → unary (('*' | '/') unary)*` (medium) - `unary → '-' unary | primary` (right-recursive for stacked unary) - `primary → NUMBER | '(' expr ')'` - Left associativity falls out naturally from the `while` loops in `_expr` and `_term`. - Unary is right-recursive (`-` `-` 5 → nested Unary) as is conventional. - Empty input detected early at `parse()` entry before any descent. - Trailing tokens detected after `_expr()` returns, before EOF check. ## Test count: 31 (20 parser + 11 existing lexer)