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