docs: def _add(self, *rules):
          # type: (Iterable[Type[Rule]]) -> Generator[Type[Rule]]
          """
          Add rules into the set. Each rule is validated and split if needed.
          The method add the rules into dictionary, so the rule can be deleted with terminals or nonterminals.
          :param rules: Rules to insert.
          :return: Inserted rules.
          :raise NotRuleException: If the parameter doesn't inherit from Rule.
          :raise RuleException: If the syntax of the rule is invalid.
          """
          for rule in rules:
              if rule in self:
                  continue
              self._validate_rule(rule)
          for rule in rules:
              for r in self._split_rules(rule):
                  for side in r.rule:
                      for s in side:
                          self._assign_map[s].add(r)
                  super().add(r)
                  yield r