CODE-0006 · claude-opus-4-8 (high)import re
def eval_expr(s):
tokens = _tokenize(s)
parser = _Parser(tokens)
result = parser.parse()
if isinstance(result, float) and result.is_integer():
return int(result)
return result
def _tokenize(s):
tokens = []
i = 0
n = len(s)
num_re = re.compile(r'\d+(\.\d+)?|\.\d+')
while i < n:
c = s[i]
if c.isspace():
i += 1
continue
if c in '+-*/()':
tokens.append(c)
i += 1
continue
m = num_re.match(s, i)
if m:
tokens.append(('num', float(m.group())))
i = m.end()
continue
raise ValueError("unknown token: " + c)
return tokens
class _Parser:
def __init__(self, tokens):
self.tokens = tokens
self.pos = 0
def peek(self):
if self.pos < len(self.tokens):
return self.tokens[self.pos]
return None
def advance(self):
tok = self.tokens[self.pos]
self.pos += 1
return tok
def parse(self):
if not self.tokens:
raise ValueError("empty input")
result = self.parse_expr()
if self.pos != len(self.tokens):
raise ValueError("unexpected token")
return result
def parse_expr(self):
value = self.parse_term()
while True:
tok = self.peek()
if tok == '+':
self.advance()
value = value + self.parse_term()
elif tok == '-':
self.advance()
value = value - self.parse_term()
else:
break
return value
def parse_term(self):
value = self.parse_factor()
while True:
tok = self.peek()
if tok == '*':
self.advance()
value = value * self.parse_factor()
elif tok == '/':
self.advance()
divisor = self.parse_factor()
if divisor == 0:
raise ValueError("division by zero")
value = value / divisor
else:
break
return value
def parse_factor(self):
tok = self.peek()
if tok == '+':
self.advance()
return self.parse_factor()
if tok == '-':
self.advance()
return -self.parse_factor()
return self.parse_atom()
def parse_atom(self):
tok = self.peek()
if tok is None:
raise ValueError("unexpected end of input")
if tok == '(':
self.advance()
value = self.parse_expr()
if self.peek() != ')':
raise ValueError("mismatched parentheses")
self.advance()
return value
if isinstance(tok, tuple) and tok[0] == 'num':
self.advance()
return tok[1]
raise ValueError("unexpected token")