docs: def parse_shape(x, pattern: str):
      """
      Parse a tensor shape to dictionary mapping axes names to their lengths.
      Use underscore to skip the dimension in parsing.
      >>> x = np.zeros([2, 3, 5, 7])
      >>> parse_shape(x, 'batch _ h w')
      {'batch': 2, 'h': 5, 'w': 7}
  
      parse_shape output can be used to specify axes_lengths for other operations
      >>> y = np.zeros([700])
      >>> rearrange(y, '(b c h w) -> b c h w', **parse_shape(x, 'b _ h w')).shape
      (2, 10, 5, 7)
  
      For symbolic frameworks may return symbols, not integers.
      :param x: tensor of any of supported frameworks
      :param pattern: str, space separated names for axes, underscore means skip axis
      :return: dict, maps axes names to their lengths
      """
      names = [elementary_axis for elementary_axis in pattern.split(' ') if len(elementary_axis) > 0]
      shape = get_backend(x).shape(x)
      if len(shape) != len(names):
          raise RuntimeError("Can't parse shape with different number of dimensions: {pattern} {shape}".format(
              pattern=pattern, shape=shape))
      result = {}
      for axis_name, axis_length in zip(names, shape):
          if axis_name != '_':
              result[axis_name] = axis_length
      return result