CODE-0006 · claude-sonnet-5 (high)
def _tokenize(s):
    tokens = []
    i = 0
    n = len(s)
    while i < n:
        c = s[i]
        if c.isspace():
            i += 1
            continue
        if c.isdigit():
            j = i
            while j < n and s[j].isdigit():
                j += 1
            if j < n and s[j] == '.':
                j += 1
                if j >= n or not s[j].isdigit():
                    raise ValueError(
                        "malformed number literal at position {}".format(i)
                    )
                while j < n and s[j].isdigit():
                    j += 1
            tokens.append(('NUMBER', s[i:j]))
            i = j
            continue
        if c in '+-*/()':
            tokens.append((c, c))
            i += 1
            continue
        raise ValueError("unexpected character {!r} at position {}".format(c, i))
    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_expr(self):
        value = self.parse_term()
        while True:
            tok = self._peek()
            if tok is not None and tok[0] in ('+', '-'):
                self._advance()
                rhs = self.parse_term()
                if tok[0] == '+':
                    value = value + rhs
                else:
                    value = value - rhs
            else:
                break
        return value

    def parse_term(self):
        value = self.parse_factor()
        while True:
            tok = self._peek()
            if tok is not None and tok[0] in ('*', '/'):
                self._advance()
                rhs = self.parse_factor()
                if tok[0] == '*':
                    value = value * rhs
                else:
                    if rhs == 0:
                        raise ValueError("division by zero")
                    value = value / rhs
            else:
                break
        return value

    def parse_factor(self):
        tok = self._peek()
        if tok is None:
            raise ValueError("unexpected end of expression")
        if tok[0] == '+':
            self._advance()
            return +self.parse_factor()
        if tok[0] == '-':
            self._advance()
            return -self.parse_factor()
        return self.parse_primary()

    def parse_primary(self):
        tok = self._peek()
        if tok is None:
            raise ValueError("unexpected end of expression")
        if tok[0] == 'NUMBER':
            self._advance()
            return float(tok[1])
        if tok[0] == '(':
            self._advance()
            value = self.parse_expr()
            tok2 = self._peek()
            if tok2 is None or tok2[0] != ')':
                raise ValueError("mismatched parentheses")
            self._advance()
            return value
        raise ValueError("unexpected token {!r}".format(tok[1]))


def eval_expr(s):
    if not isinstance(s, str):
        raise ValueError("expression must be a string")

    tokens = _tokenize(s)
    if not tokens:
        raise ValueError("empty expression")

    parser = _Parser(tokens)
    value = parser.parse_expr()

    if parser.pos != len(tokens):
        extra = parser.tokens[parser.pos]
        raise ValueError("unexpected token {!r}".format(extra[1]))

    if isinstance(value, float) and value.is_integer():
        return int(value)
    return value