CODE-0006 · claude-sonnet-5 (high)import re
def eval_expr(s):
token_spec = [
('NUMBER', r'\d+(?:\.\d+)?'),
('PLUS', r'\+'),
('MINUS', r'-'),
('TIMES', r'\*'),
('DIVIDE', r'/'),
('LPAREN', r'\('),
('RPAREN', r'\)'),
('SKIP', r'\s+'),
('MISMATCH', r'.'),
]
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_spec)
tokens = []
for mo in re.finditer(tok_regex, s):
kind = mo.lastgroup
value = mo.group()
if kind == 'NUMBER':
tokens.append(('NUMBER', value))
elif kind == 'SKIP':
continue
elif kind == 'MISMATCH':
raise ValueError('Unknown token: %r' % value)
else:
tokens.append((kind, value))
if not tokens:
raise ValueError('Empty expression')
pos = [0]
def peek():
if pos[0] < len(tokens):
return tokens[pos[0]]
return None
def advance():
tok = tokens[pos[0]]
pos[0] += 1
return tok
def parse_expr():
value = parse_term()
while True:
tok = peek()
if tok and tok[0] in ('PLUS', 'MINUS'):
advance()
right = parse_term()
if tok[0] == 'PLUS':
value = value + right
else:
value = value - right
else:
break
return value
def parse_term():
value = parse_factor()
while True:
tok = peek()
if tok and tok[0] in ('TIMES', 'DIVIDE'):
advance()
right = parse_factor()
if tok[0] == 'TIMES':
value = value * right
else:
if right == 0:
raise ValueError('Division by zero')
value = value / right
else:
break
return value
def parse_factor():
tok = peek()
if tok is None:
raise ValueError('Unexpected end of expression')
if tok[0] == 'PLUS':
advance()
return parse_factor()
if tok[0] == 'MINUS':
advance()
return -parse_factor()
return parse_primary()
def parse_primary():
tok = peek()
if tok is None:
raise ValueError('Unexpected end of expression')
if tok[0] == 'NUMBER':
advance()
val = tok[1]
if '.' in val:
return float(val)
else:
return int(val)
if tok[0] == 'LPAREN':
advance()
value = parse_expr()
tok2 = peek()
if tok2 is None or tok2[0] != 'RPAREN':
raise ValueError('Mismatched parentheses')
advance()
return value
raise ValueError('Unexpected token: %r' % tok[1])
result = parse_expr()
if pos[0] != len(tokens):
raise ValueError('Unexpected token at end of expression')
if isinstance(result, float) and result.is_integer():
return int(result)
return result