docs: def epsilon_rules_restore(root):
      # type: (Nonterminal) -> Nonterminal
      """
      Transform parsed tree to contain epsilon rules originally removed from the grammar.
      :param root: Root of the parsed tree.
      :return: Modified tree including epsilon rules.
      """
      items = Traversing.post_order(root)
      items = filter(lambda x: isinstance(x, EpsilonRemovedRule), items)
      for rule in items:
          # create original rule
          created_rule = rule.from_rule()  # type: Rule
          # attach parrents parents
          for s in rule.from_symbols:  # type: Nonterminal
              s._set_to_rule(created_rule)
              created_rule._from_symbols.append(s)
          # attach children up to replace index (that will contain epsilon)
          for i in range(rule.replace_index):
              ch = rule.to_symbols[i]  # type: Nonterminal
              ch._set_from_rule(created_rule)
              created_rule._to_symbols.append(ch)
          # add symbols originally rewrote to epsilon
          symb = _restore_tree_for(created_rule.right[rule.replace_index], rule.backtrack)  # type: Nonterminal
          created_rule._to_symbols.append(symb)
          symb._set_from_rule(created_rule)
          # attach rest of children
          for i in range(rule.replace_index, len(rule.to_symbols)):
              ch = rule.to_symbols[i]  # type: Nonterminal
              ch._set_from_rule(created_rule)
              created_rule._to_symbols.append(ch)
      return root