from consts import * class Node: def __init__(self, node_type, value=None, subtype=None): self.type = node_type self.value = value self.subtype = subtype self.parent = None self.right = None self.left = None def __eq__(self, other): return self.type == other.type and self.value == other.value def __repr__(self): if self.type == TokenType.LEFT_PARENTHESIS: return "Node(LEFT_PARENTHESIS)" if self.type == TokenType.RIGHT_PARENTHESIS: return "Node(RIGHT_PARENTHESIS)" if self.type == TokenType.NUMBER: return f"Node({self.value})" if self.type == TokenType.OPERATOR: return f"Node({self.subtype})" if self.type == TokenType.COMMA: return f"Node(COMMA)" if self.type == TokenType.SYMBOL: return f"Node(SYMBOL {self.value})" if self.type == FUNCALL: return f"Node(FUNCALL {self.value})" __str__ = __repr__ def parse_parenthesis(tokens, start): end = start depth = 0 while True: token = tokens[end] if token.type == TokenType.RIGHT_PARENTHESIS: depth -= 1 if token.type == TokenType.LEFT_PARENTHESIS: depth += 1 if depth == 0 and token.type == TokenType.RIGHT_PARENTHESIS: break end += 1 node = build_tree(tokens[start + 1: end]) return node, end def parse_args(tokens, start): end = start depth = 0 while True: token = tokens[end] if token.type == TokenType.RIGHT_PARENTHESIS: depth -= 1 if token.type == TokenType.LEFT_PARENTHESIS: depth += 1 if depth == 0 and token.type == TokenType.RIGHT_PARENTHESIS: break end += 1 args = [] arg = [] for token in tokens[start + 1: end]: if token.type != TokenType.COMMA: arg.append(token) else: args.append(arg.copy()) arg.clear() if len(arg) != 0: args.append(arg) return list(map(build_tree, args)) def build_tree(tokens): state = State.NAME i = 0 current_node = None while i < len(tokens): token = tokens[i] if state == State.OPERATOR and token.type == TokenType.LEFT_PARENTHESIS: args = parse_args(tokens, i) current_node.type = FUNCALL current_node.value = (current_node.value, args) elif token.type in [TokenType.LEFT_PARENTHESIS, TokenType.NUMBER, TokenType.SYMBOL] or token.subtype == UNARY: if token.type == TokenType.LEFT_PARENTHESIS: node, i = parse_parenthesis(tokens, i) state = State.NAME elif token.type == TokenType.NUMBER: node = Node(TokenType.NUMBER, value=token.value) state = State.OPERATOR elif token.type == TokenType.SYMBOL: node = Node(TokenType.SYMBOL, value=token.value) state = State.OPERATOR elif token.subtype == UNARY: node = Node(TokenType.OPERATOR, subtype=UNARY) node.left = Node(TokenType.OPERATOR, subtype=token.value) state = State.NAME if current_node is None: current_node = node elif current_node.type == TokenType.NUMBER: raise ValueError("Not a valid expression") elif current_node.type == TokenType.OPERATOR: if current_node.left is None: current_node.left = node node.parent = current_node elif current_node.right is None: current_node.right = node node.parent = current_node current_node = node else: raise ValueError("Not a valid expression") elif token.type == TokenType.OPERATOR: node = Node(token.type, subtype=token.subtype, value=token.value) if current_node is None: raise ValueError("Not a valid expression") elif current_node.type in [TokenType.NUMBER, TokenType.OPERATOR, FUNCALL]: while current_node.parent is not None: if PRECEDENCE[current_node.parent.subtype] < PRECEDENCE[node.subtype]: node.parent = current_node.parent if node.parent is not None: node.parent.right = node break current_node = current_node.parent current_node.parent = node node.left = current_node current_node = node else: print(current_node, token) raise ValueError("Not a valid expression") state = State.NAME i += 1 while current_node.parent is not None: current_node = current_node.parent return current_node