docs: def print(root):
          # type: (Union[Nonterminal,Terminal,Rule])-> str
          """
          Transform the parsed tree to the string. Expects tree like structure.
          You can see example output below.
  
          (R)SplitRules26
          |--(N)Iterate
          |  `--(R)SplitRules30
          |     `--(N)Symb
          |        `--(R)SplitRules4
          |           `--(T)e
          `--(N)Concat
             `--(R)SplitRules27
                `--(N)Iterate
                   `--(R)SplitRules30
                      `--(N)Symb
                         `--(R)SplitRules5
                            `--(T)f
  
          :param root: Root node of the parsed tree.
          :return: String representing the parsed tree (ends with newline).
          """
          # print the part before the element
          def print_before(previous=0, defined=None, is_last=False):
              defined = defined or {}
              ret = ''
              if previous != 0:
                  for i in range(previous - 1):
                      # if the column is still active write |
                      if i in defined:
                          ret += '|  '
                      # otherwise just print space
                      else:
                          ret += '   '
                  # if is current element last child, don't print |-- but `-- instead
                  ret += '`--' if is_last else '|--'
              return ret
  
          # print the terminal
          def terminal_traverse(term, callback, previous=0, defined=None, is_last=False):
              before = print_before(previous, defined, is_last)
              yield before + '(T)' + str(term.s) + '\n'
  
          # print the nonterminal
          def nonterminal_traverse(nonterm, callback, previous=0, defined=None, is_last=False):
              before = print_before(previous, defined, is_last)
              yield before + '(N)' + nonterm.__class__.__name__ + '\n'
              yield callback(nonterm.to_rule, previous + 1, defined, True)
  
          # print the rule
          def rule_traverse(rule, callback, previous=0, defined=None, is_last=False):
              # print the rule name
              before = print_before(previous, defined, is_last)
              yield before + '(R)' + rule.__class__.__name__ + '\n'
              # register new column
              defined = defined or set()
              defined.add(previous)
              # print all childs except the last one
              for i in range(len(rule.to_symbols) - 1):
                  yield callback(rule.to_symbols[i], previous + 1, defined, False)
              # unregister the column as last child print it automatically
              defined.remove(previous)
              yield callback(rule.to_symbols[-1], previous + 1, defined, True)
  
          res = Traversing.traverse_separated(root, rule_traverse, nonterminal_traverse, terminal_traverse)
          return str.join("", res)