docs: def traverse(root, callback, *args, **kwargs):
          # type: (Nonterminal, Callable[[Any, Callable, Any, Any], Generator], Any, Any) -> Generator
          """
          Traverse AST based on callback.
          :param root: Root element of the parsed tree.
          :param callback: Function that accepts current node, callback `c_2` and parameters from the parent.
          Function 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` call.
  
          Example of pre-order traversing:
          def traverse_func(item, callback):
              if isinstance(item, Rule):
                  yield item
                  for el in item.to_symbols:
                      yield callback(el)
              elif isinstance(item, Nonterminal):
                  yield item
                  yield callback(item.to_rule)
              else:
                  yield item
  
          :return: Sequence of nodes to traverse.
          """
          class MyGenerator:
              def __init__(self, gen):
                  self._gen = gen
              def __next__(self):
                  return next(self._gen)
  
          def inner_callback(item, *args, **kwargs):
              return MyGenerator(callback(item, inner_callback, *args, **kwargs))
  
          to_call = list()
          to_call.append(inner_callback(root, *args, **kwargs))
          while len(to_call) > 0:
              current = to_call.pop()
              try:
                  el = next(current)
                  to_call.append(current)
                  if isinstance(el, MyGenerator):
                      to_call.append(el)
                  else:
                      yield el
              except StopIteration:
                  continue