code: def table_source(self, tree):
      left_node = None
      join_nodes = []
  
      for child in tree.children:
          if isinstance(child, Tree):
              if child.data == "table_source_item_with_param":
                  left_node = self.visit(child)
                  join_nodes = [left_node]
              elif child.data.endswith("join"):
                  table = self.visit(child)
                  join_nodes.append(table)
  
      num_table_joins = len(join_nodes)
  
      # Join Nodes
      if num_table_joins > 1:
          # Add Join nodes -> left deep tree
          # t1, t2, t3 -> j2 ( j1 ( t1, t2 ), t3 )
          for i in range(num_table_joins - 1):
              join_nodes[i + 1].join_node.left = join_nodes[i]
  
          return join_nodes[-1]
      else:
          return join_nodes[0]
  
imports: from lark import Token, Tree
  from evadb.expression.tuple_value_expression import TupleValueExpression
  from evadb.parser.select_statement import SelectStatement
  from evadb.parser.table_ref import Alias, JoinNode, TableRef, TableValuedExpression
  from evadb.parser.types import JoinType
  from evadb.utils.logging_manager import logger
label_desc: Use image node_id 3 for calling the TableSources obj's underlying member method code with example usage: obj.table_source(tree) and returns: join_nodes, join_nodes