Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
3.1 kB
3
Indexable
Never
OP_PLUS = 0
OP_MINUS = 1


class BinaryOp:

    def __init__(self):
        self.left = None
        self.right = None
        self.operation = None

    def calculate(self):
        left_res = None
        if isinstance(self.left, BinaryOp):
            left_res = self.left.calculate()
        elif isinstance(self.left, int):
            left_res = self.left

        right_res = None
        if isinstance(self.right, BinaryOp):
            right_res = self.right.calculate()
        elif isinstance(self.right, int):
            right_res = self.right

        if self.operation == OP_PLUS:
            return left_res + right_res
        elif self.operation == OP_MINUS:
            return left_res - right_res

    def is_filled(self):
        return self.left is not None and self.right is not None and self.operation is not None

    def __repr__(self) -> str:
        left_s = ''
        if isinstance(self.left, int):
            left_s = str(self.left)
        elif isinstance(self.left, BinaryOp):
            left_s = self.left.__repr__()

        right_s = ''
        if isinstance(self.right, int):
            right_s = str(self.right)
        elif isinstance(self.right, BinaryOp):
            right_s = self.right.__repr__()

        return '%s %s %s' % (left_s, self.operation, right_s)


class Parser:

    def __init__(self):
        self.digit = ''
        self.prev_op = None
        self.current_op: BinaryOp = None
        self.is_in_digit = False

        self.is_bracket_open = False

    def clear_digit(self):
        self.is_in_digit = False
        self.digit = ''

    def parse(self, str_expr):
        str_expr += ' '

        for s in str_expr:
            print(s)

            if self.current_op and self.current_op.is_filled():
                self.prev_op = self.current_op
                self.current_op = BinaryOp()
                self.current_op.left = self.prev_op

            if s.isdigit():
                self.is_in_digit = True
                self.digit += s
            elif s == ' ' or s == ')':
                if self.is_in_digit:

                    if self.current_op is None:
                        self.current_op = BinaryOp()

                    if self.current_op.left is None:
                        self.current_op.left = int(self.digit)
                        self.clear_digit()
                    elif self.current_op.right is None:
                        self.current_op.right = int(self.digit)
                        self.clear_digit()

            elif s == '+':
                if self.current_op:
                    self.current_op.operation = OP_PLUS
                else:
                    raise Exception('Error')
            elif s == '-':
                if self.current_op:
                    self.current_op.operation = OP_MINUS
            elif s == '(':
                self.is_bracket_open = True
                self.current_op = BinaryOp()

            if s == ')':
                self.is_bracket_open = False