CODE-0006 · gemini-3.1-flash-lite (default)import re
def eval_expr(s):
tokens = re.findall(r'\d*\.\d+|\d+|[+\-*/()]', s)
if not tokens:
raise ValueError("Empty or invalid expression")
pos = 0
def parse_expr():
nonlocal pos
node = parse_term()
while pos < len(tokens) and tokens[pos] in ('+', '-'):
op = tokens[pos]
pos += 1
right = parse_term()
if op == '+': node += right
else: node -= right
return node
def parse_term():
nonlocal pos
node = parse_factor()
while pos < len(tokens) and tokens[pos] in ('*', '/'):
op = tokens[pos]
pos += 1
right = parse_factor()
if op == '*': node *= right
else:
if right == 0: raise ValueError("Division by zero")
node /= right
return node
def parse_factor():
nonlocal pos
if pos >= len(tokens): raise ValueError("Unexpected end of expression")
token = tokens[pos]
if token == '+':
pos += 1
return parse_factor()
if token == '-':
pos += 1
return -parse_factor()
if token == '(':
pos += 1
val = parse_expr()
if pos >= len(tokens) or tokens[pos] != ')':
raise ValueError("Mismatched parentheses")
pos += 1
return val
try:
val = float(token)
pos += 1
return int(val) if val.is_integer() else val
except ValueError:
raise ValueError(f"Unknown token: {token}")
res = parse_expr()
if pos < len(tokens):
raise ValueError("Dangling operator or invalid syntax")
if isinstance(res, float) and res.is_integer():
return int(res)
return res