Calling eval on user input is a security hole, so calculators, spreadsheet formulas and LLM tool-calling "calculator" tools parse expressions themselves.
Implement evaluate(expr) for expressions containing:
3.5), +, -, *, /, parentheses and spaces;-3, 2 * -(1 + 1));* and / before + and -) and left-to-right associativity (8 - 3 - 2 is 3).Return a float. Raise ValueError for malformed input such as unbalanced parentheses, unknown characters, a trailing operator or an empty string. Raise ZeroDivisionError for division by zero.
Don't use eval, exec, compile or the ast module. A recursive-descent parser works well:
expr := term (('+' | '-') term)*
term := factor (('*' | '/') factor)*
factor := '-' factor | number | '(' expr ')'