Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import re
- from collections import deque
- from abc import ABC, abstractmethod
- class Operator(ABC):
- def __init__(self):
- self.value = ''
- @abstractmethod
- def operate(self, op1, op2):
- pass
- @abstractmethod
- def precedence(self) -> int:
- pass
- def __repr__(self) -> str:
- return self.value
- class Addition(Operator):
- def __init__(self):
- super().__init__()
- self.value = '+'
- def operate(self, op1, op2):
- return Operand(str(op1.getvalue() + op2.getvalue()))
- def precedence(self) -> int:
- return 2
- class Multiplication(Operator):
- def __init__(self):
- super().__init__()
- self.value = '*'
- def operate(self, op1, op2):
- return Operand(str(op1.getvalue() * op2.getvalue()))
- def precedence(self) -> int:
- return 3
- class Division(Operator):
- def __init__(self):
- super().__init__()
- self.value = '/'
- def operate(self, op1, op2):
- return Operand(str(op1.getvalue() / op2.getvalue()))
- def precedence(self) -> int:
- return 4
- class Operand:
- def __init__(self, value):
- self.value = value
- def getvalue(self):
- return float(self.value)
- def __repr__(self) -> str:
- return self.value
- class Expression:
- def __init__(self, infixexpr: str, operators_cls: list) -> None:
- self.postfixlist = None
- self.infixexpr = infixexpr
- # Precedence setting
- self.op_to_cls = {str(op()): op() for op in operators_cls}
- self.precedence = {str(v): v.precedence() for k, v in self.op_to_cls.items()}
- def infixToPostfixList(self) -> list:
- infixexpr = self.infixexpr
- opStack = deque()
- postfixList = []
- number_or_symbol = re.compile('(\d+|[^ 0-9])')
- print(re.findall(number_or_symbol, infixexpr))
- for token in re.findall(number_or_symbol, infixexpr):
- if token.isnumeric():
- postfixList.append(Operand(token))
- elif token == '(':
- opStack.append(token)
- elif token == ')':
- topToken = opStack.pop()
- while topToken != '(':
- postfixList.append(self.op_to_cls[topToken])
- topToken = opStack.pop()
- else:
- while opStack and \
- (self.precedence[opStack[-1]] >= self.precedence[token]):
- postfixList.append(self.op_to_cls[opStack.pop()])
- opStack.append(token)
- while opStack:
- postfixList.append(self.op_to_cls[opStack.pop()])
- self.postfixlist = postfixList
- return self.postfixlist
- def evaluate(self):
- stack = deque()
- for term in self.postfixlist:
- print(stack, term)
- if isinstance(term, Operand):
- stack.append(term)
- elif isinstance(term, Operator):
- r = stack.pop()
- l = stack.pop()
- stack.append(term.operate(l, r))
- else:
- print("Unknown:", term)
- return stack.pop()
- if __name__ == '__main__':
- operators = [Addition, Multiplication, Division]
- exp = "1+2+35/ 5+5*7" # *35 1+2+35/ 5+5*7
- print(exp)
- e = Expression(exp, operators)
- print(e.infixToPostfixList())
- print(e.evaluate())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement