def _find_from_table(item, example, reverse=False):
  """Finds the table that is being queried.

  Args:
    item: position in the SQL parse where the search will start.
    example: the QuikExample containing the table annotations.
    reverse: if True will use backward search, otherwise forward.

  Returns:
    a list of QuikAnnotation that are tables or None.
  """
  parent = item.parent
  next_token_index = parent.token_index(item)
  next_item = item

  # Here we iterate over al the possible tokens in the current level until we
  # reach a FROM statement.
  def _next_token():
    if reverse:
      return parent.token_prev(next_token_index)
    else:
      return parent.token_next(next_token_index)

  down_exploration = False

  while True:
    prev_item = next_item
    next_token_index, next_item = _next_token()

    if next_item is None:
      # Go up
      if (not down_exploration and
          (_is_identifier_list(parent) or _is_identifier(parent) or
           _is_comparison(parent) or _is_where(parent) or
           _is_operation(parent) or _is_parenthesis(parent) or
           _is_function(parent) or _is_select(parent))):
        next_token_index = parent.parent.token_index(parent)
        next_item = parent
        parent = parent.parent

      # Go down
      elif hasattr(prev_item, 'tokens') and len(prev_item.tokens) > 1:
        next_token_index = prev_item.token_index(prev_item.tokens[0])
        next_item = prev_item.tokens[0]
        parent = prev_item
        down_exploration = True
      else:
        return None

    if _is_from(next_item):
      next_token_index, next_item = parent.token_next(next_token_index)

      tables = list()
      tables.append(_find_table_annotation(next_item, example))

      next_token_index, next_item = parent.token_next(next_token_index)

      if next_item and next_item.value.lower() == 'join':
        next_token_index, next_item = parent.token_next(next_token_index)
        tables.append(_find_table_annotation(next_item, example))

      return tables
Finds the table that is being queried.

  Args:
    item: position in the SQL parse where the search will start.
    example: the QuikExample containing the table annotations.
    reverse: if True will use backward search, otherwise forward.

  Returns:
    a list of QuikAnnotation that are tables or None.
  
language/xsp/data_preprocessing/sql_parsing.py