docs: def nfa_dot_importer(input_file: str) -> dict:
      """ Imports a NFA from a DOT file.
  
      Of .dot files are recognized the following attributes
        • nodeX   shape=doublecircle -> accepting node;
        • nodeX   root=true -> initial node;
        • edgeX   label="a" -> action in alphabet;
        • fakeX    style=invisible -> dummy invisible nodes pointing
                  to initial state (it will be skipped);
        • fakeX->S [style=bold] -> dummy transitions to draw arrows
                  pointing to initial states (they will be skipped).
  
      All invisible nodes are skipped.
  
      Forbidden names:
        • 'fake'  used for graphical purpose to drawn the arrow of
          the initial state
        • 'sink'  used as additional state when completing a NFA
  
      Forbidden characters:
        • "
        • '
        • (
        • )
        • spaces
  
      :param str input_file: Path to input DOT file;
      :return: *(dict)* representing a NFA.
      """
  
      # pyDot Object
      g = pydot.graph_from_dot_file(input_file)[0]
  
      states = set()
      initial_states = set()
      accepting_states = set()
  
      replacements = {'"': '', "'": '', '(': '', ')': '', ' ': ''}
  
      for node in g.get_nodes():
          attributes = node.get_attributes()
          if node.get_name() == 'fake' \
                  or node.get_name() == 'None' \
                  or node.get_name() == 'graph' \
                  or node.get_name() == 'node':
              continue
          if 'style' in attributes \
                  and attributes['style'] == 'invisible':
              continue
  
          node_reference = __replace_all(replacements,
                                         node.get_name()).split(',')
          if len(node_reference) > 1:
              node_reference = tuple(node_reference)
          else:
              node_reference = node_reference[0]
          states.add(node_reference)
          for attribute in attributes:
              if attribute == 'root':
                  initial_states.add(node_reference)
              if attribute == 'shape' \
                      and attributes['shape'] == 'doublecircle':
                  accepting_states.add(node_reference)
  
      alphabet = set()
      transitions = {}
      for edge in g.get_edges():
          source = __replace_all(replacements,
                                 edge.get_source()).split(',')
          if len(source) > 1:
              source = tuple(source)
          else:
              source = source[0]
          destination = __replace_all(replacements,
                                      edge.get_destination()).split(',')
          if len(destination) > 1:
              destination = tuple(destination)
          else:
              destination = destination[0]
  
          if source not in states or destination not in states:
              continue
  
          label = __replace_all(replacements, edge.get_label())
          alphabet.add(label)
  
          transitions.setdefault((source, label), set()).add(
              destination)
  
      nfa = {
          'alphabet': alphabet,
          'states': states,
          'initial_states': initial_states,
          'accepting_states': accepting_states,
          'transitions': transitions
      }
  
      return nfa