code: def parse(cls, filepath, filecontent, parser):
      
      try:
        objects = parser.parse(filepath, filecontent)
      except Exception as e:
        raise MappingError('Failed to parse {}:\n{}'.format(filepath, e))
      objects_by_name = {}
      for obj in objects:
        if not Serializable.is_serializable(obj):
          raise UnaddressableObjectError('Parsed a non-serializable object: {!r}'.format(obj))
        attributes = obj._asdict()
  
        name = attributes.get('name')
        if not name:
          raise UnaddressableObjectError('Parsed a non-addressable object: {!r}'.format(obj))
  
        if name in objects_by_name:
          raise DuplicateNameError('An object already exists at {!r} with name {!r}: {!r}.  Cannot '
                                   'map {!r}'.format(filepath, name, objects_by_name[name], obj))
        objects_by_name[name] = obj
      return cls(filepath, OrderedDict(sorted(objects_by_name.items())))
docs: Parses a source for addressable Serializable objects.
  
      No matter the parser used, the parsed and mapped addressable objects are all 'thin'; ie: any
      objects they point to in other namespaces or even in the same namespace but from a seperate
      source are left as unresolved pointers.
  
      :param string filepath: The path to the byte source containing serialized objects.
      :param string filecontent: The content of byte source containing serialized objects to be parsed.
      :param symbol_table: The symbol table cls to expose a symbol table dict.
      :type symbol_table: Instance of :class:`pants.engine.parser.SymbolTable`.
      :param parser: The parser cls to use.
      :type parser: A :class:`pants.engine.parser.Parser`.