Skip to content

Instantly share code, notes, and snippets.

@urielha
Last active November 12, 2017 00:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save urielha/6c11c29073dddbb9a0b9a1b92c1af3be to your computer and use it in GitHub Desktop.
Save urielha/6c11c29073dddbb9a0b9a1b92c1af3be to your computer and use it in GitHub Desktop.
Python Calculator line parser recursive
class Calculator():
def __init__(self, s):
self._s = s
self._i = 0
self._len = len(s)
self._err = False
def next(self):
self._i += 1
def take(self):
l = self._len
j = i = self._i
s = self._s
if j<l and s[j] == '(':
self.next()
n = self.calc()
if s[self._i] != ')':
raise Exception()
self.next()
return n
while j < l and s[j].isdigit():
j += 1
self._i = j
if i == j:
raise Exception()
return int(s[i:j])
def poww(self):
res = self.take()
l = self._len
s = self._s
while self._i < l and s[self._i] == '^':
self.next()
num = self.take()
res = res**num
return res
def mul_div(self):
res = self.poww()
l = self._len
s, i = self._s, self._i
while self._i < l and s[self._i] in ('/', '*'):
op = s[self._i]
self.next()
num = self.poww()
if op == '*':
res *= num
if op == '/':
res /= num
return res
def plus_minus(self):
res = self.mul_div()
l = self._len
s, i = self._s, self._i
while self._i < l and s[self._i] in ('+', '-'):
op = s[self._i]
self.next()
num = self.mul_div()
if op == '+':
res += num
if op == '-':
res -= num
return res
def calc(self):
try:
return self.plus_minus()
except:
if not self._err:
print('Parsing Error at index {}'.format(self._i))
self._err = True
return None
Calculator("(1+2)*(7-2)^2").calc() # 75
Calculator("1+*2").calc() # err
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment