CODE-0006 · grok-4.3 (default)import re
def tokenize(s):
token_pattern = r'\s*((\d+\.?\d*)|[-+*/()])\s*'
tokens = []
for match in re.finditer(token_pattern, s):
tok = match.group(1)
if tok in '+-*/()':
tokens.append(tok)
else:
if '.' in tok:
tokens.append(float(tok))
else:
tokens.append(int(tok))
if ''.join(re.findall(r'\S', s)) != ''.join(str(t) for t in tokens if not isinstance(t, (int, float))):
# rough check for invalid chars, but mainly rely on pattern
pass
cleaned = re.sub(r'\s+', '', s)
reconstructed = ''.join(str(t) for t in tokens)
if cleaned != reconstructed:
raise ValueError("Malformed")
return tokens
class Parser:
def __init__(self, tokens):
self.tokens = tokens
self.pos = 0
def peek(self):
return self.tokens[self.pos] if self.pos < len(self.tokens) else None
def consume(self):
tok = self.peek()
self.pos += 1
return tok
def parse(self):
if not self.tokens:
raise ValueError("Empty input")
val = self.expr()
if self.peek() is not None:
raise ValueError("Malformed expression")
return val
def expr(self):
val = self.term()
while self.peek() in ('+', '-'):
op = self.consume()
right = self.term()
val = val + right if op == '+' else val - right
return val
def term(self):
val = self.factor()
while self.peek() in ('*', '/'):
op = self.consume()
right = self.factor()
if op == '*':
val *= right
else:
if right == 0:
raise ValueError("Division by zero")
val /= right
return val
def factor(self):
tok = self.peek()
if tok in ('+', '-'):
op = self.consume()
val = self.factor()
return val if op == '+' else -val
elif tok == '(':
self.consume()
val = self.expr()
if self.consume() != ')':
raise ValueError("Mismatched parentheses")
return val
elif isinstance(tok, (int, float)):
self.consume()
return tok
else:
raise ValueError("Unexpected token")
def eval_expr(s):
try:
tokens = tokenize(s)
except:
raise ValueError("Malformed expression")
parser = Parser(tokens)
result = parser.parse()
if isinstance(result, float) and result.is_integer():
return int(result)
return result