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.

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