CODE-0006 · deepseek-v4-pro (default)def tokenize(s):
tokens = []
i = 0
n = len(s)
while i < n:
if s[i].isspace():
i += 1
continue
c = s[i]
if c.isdigit():
j = i
while j < n and s[j].isdigit():
j += 1
if j < n and s[j] == '.':
j += 1
while j < n and s[j].isdigit():
j += 1
num_str = s[i:j]
if '.' in num_str:
tokens.append(('NUMBER', float(num_str)))
else:
tokens.append(('NUMBER', int(num_str)))
i = j
elif c == '.':
j = i + 1
if j < n and s[j].isdigit():
while j < n and s[j].isdigit():
j += 1
num_str = s[i:j]
tokens.append(('NUMBER', float(num_str)))
i = j
else:
raise ValueError(f"Unexpected character: {c}")
elif c in '+-*/()':
tokens.append((c, None))
i += 1
else:
raise ValueError(f"Unexpected character: {c}")
return tokens
def eval_expr(s):
tokens = tokenize(s)
if not tokens:
raise ValueError("Empty expression")
pos = 0
def peek():
if pos >= len(tokens):
return ('EOF', None)
return tokens[pos]
def advance():
nonlocal pos
pos += 1
def consume(expected_type):
tok = peek()
if tok[0] != expected_type:
raise ValueError(f"Expected {expected_type}, got {tok[0]}")
advance()
return tok
def expr():
val = term()
while peek()[0] in ('+', '-'):
op = peek()[0]
advance()
rhs = term()
if op == '+':
val += rhs
else:
val -= rhs
return val
def term():
val = factor()
while peek()[0] in ('*', '/'):
op = peek()[0]
advance()
rhs = factor()
if op == '*':
val *= rhs
else:
if rhs == 0:
raise ValueError("Division by zero")
val /= rhs
return val
def factor():
tok = peek()
if tok[0] in ('+', '-'):
op = tok[0]
advance()
operand = factor()
if op == '-':
return -operand
else:
return operand
else:
return atom()
def atom():
tok = peek()
if tok[0] == 'NUMBER':
advance()
return tok[1]
elif tok[0] == '(':
advance()
val = expr()
consume(')')
return val
elif tok[0] == 'EOF':
raise ValueError("Unexpected end of expression")
else:
raise ValueError(f"Unexpected token: {tok[0]}")
result = expr()
if peek()[0] != 'EOF':
raise ValueError("Unexpected extra tokens")
if isinstance(result, float) and result.is_integer() \
and not (result == float('inf') or result == float('-inf') or result != result):
return int(result)
elif isinstance(result, float):
return result
else:
return result