794 B
794 B
JOURNAL-parse
Implementation notes
Grammar chosen (standard arithmetic precedence):
expr := term (('+' | '-') term)*
term := unary (('*' | '/') unary)*
unary := '-' unary | primary
primary := NUMBER | '(' expr ')'
unary is right-recursive, which gives right-associativity to stacked unary minuses (e.g. --5 → Unary('-', Unary('-', Num(5)))). This is standard.
expr and term are iterative loops (not recursive), so same-level operators are naturally left-associative.
The ParseError class is defined in parser.py (not lexer.py) since it's the parser's concern. All five D5 error cases raise ParseError, not a generic exception.
Tests assert on exact tree structure using == on dataclasses, not on evaluation results, per the plan's requirement.