code: def traverse_separated(root, callbackRules, callbackNonterminals, callbackTerminals, *args, **kwargs):
          # type: (Nonterminal, Callable[[Rule, Callable, Any, Any], Generator], Callable[[Nonterminal, Callable, Any, Any], Generator], Callable[[Terminal, Callable, Any, Any], Generator], Any, Any) -> Generator
          
  
          def separate_traverse_callback(item, callback, *args, **kwargs):
              if isinstance(item, Rule):
                  return callbackRules(item, callback, *args, **kwargs)
              if isinstance(item, Nonterminal):
                  return callbackNonterminals(item, callback, *args, **kwargs)
              if isinstance(item, Terminal):
                  return callbackTerminals(item, callback, *args, **kwargs)
  
          return Traversing.traverse(root, separate_traverse_callback, *args, **kwargs)
docs: Same as traverse method, but have different callbacks for rules, nonterminals and terminals.
          Functions accepts current node, callback `c_2` and parameters from the parent.
          Functions must yield individual values.
          Its possible to yield callback c_2 **call** on any node to call the recursion.
          The callback can accept parameters from the parent call.
          The root will receive parameters from the `traverse_separated` call.
          :param root: Root node of the parsed tree.
          :param callbackRules: Function to call for every rule.
          :param callbackNonterminals: Function to call for every nonterminal.
          :param callbackTerminals: Function to call for every terminal.
          :return: Sequence of nodes to traverse.