class StackUnderflow(ValueError):
pass
class SStack():
def __init__(self):
self._elems = []
def is_empty(self):
return self._elems == []
def top(self):
if self._elems == []:
raise StackUnderflow
return self._elems[len(self._elems)-1]
def push(self, elem):
self._elems.append(elem)
def pop(self):
if self._elems == []:
raise StackUnderflow
return self._elems.pop()
class ESStack(SStack): #可以检查深度的栈
def depth(self):
return len(self._elems)
################################################
####### Suffix expression evaluator ############
def suffix_exp_evaluator(line):
return suf_exp_evaluator(line.split())
def suf_exp_evaluator(exp):
"""exp is a list of items representing a suffix expression.
This function evaluates it and return its value.
"""
operators = "+-*/"
st = ESStack()
for x in exp:
if not x in operators:
st.push(float(x))
continue
if st.depth() < 2:
raise SyntaxError("Short of operand(s).")
a = st.pop() # second argument
b = st.pop() # first argument
if x == "+":
c = b + a
elif x == "-":
c = b - a
elif x == "*":
c = b * a
elif x == "/":
if a == 0: raise ZeroDivisionError
c = b / a
else:
pass # This branch is not possible
st.push(c)
if st.depth() == 1:
return st.pop()
raise SyntaxError("Extra operand(s).")
# end suf_exp_evaluator
def suffix_exp_calculator():
"""Repeatly ask for expression input until an 'end'."""
while True:
try:
line = input("Suffix Expression: ")
if line == "end":
return
res = suffix_exp_evaluator(line)
print(res)
except Exception as ex:
print("Error:", type(ex), ex.args)
#####################################################
##### Transform infix expression to suffix expression
priority = {"(":1, "+":3, "-":3, "*":5, "/":5}
infix_operators = "+-*/()"
def tokens(line):
""" This function cannot deal with signed numbers,
nor unary operators.
"""
i, llen = 0, len(line)
while i < llen:
while line[i].isspace():
i += 1
if i >= llen:
break
if line[i] in infix_operators:
yield line[i]
i += 1
continue
j = i + 1
while (j < llen and not line[j].isspace() and
line[j] not in infix_operators):
if ((line[j] == 'e' or line[j] == 'E') and
j+1 < llen and line[j+1] == '-'):
j += 1
j += 1
yield line[i:j]
i = j
def trans_infix_suffix(line):
st = SStack()
llen = len(line)
exp = []
for x in tokens(line):
if x not in infix_operators:
exp.append(x)
elif st.is_empty() or x == '(':
st.push(x)
elif x == ')':
while not st.is_empty() and st.top() != "(":
exp.append(st.pop())
if st.is_empty():
raise SyntaxError("Missing \'(\'.")
st.pop() # discard left parethesis
else: # consider all ops left-associative
while (not st.is_empty() and
priority[st.top()] >= priority[x]):
exp.append(st.pop())
st.push(x)
while not st.is_empty():
if st.top() == "(":
raise SyntaxError("Extra \'(\' in expression.")
exp.append(st.pop())
return exp
Python:表达式的计算和变换
最新推荐文章于 2022-09-27 16:13:10 发布