docs: def transform_to_chomsky_normal_form(grammar, inplace=False):
      # type: (Grammar, bool) -> Grammar
      """
      Transform grammar to Chomsky Normal Form.
      :param grammar: Grammar to transform.
      :param inplace: True if transformation should be performed in place. False by default.
      :return: Grammar in Chomsky Normal Form.
      """
      # Copy if required
      if inplace is False:
          grammar = copy(grammar)
      # Create nonterminals rewritable to the terminal.
      # They will be inserted into the grammar as needed.
      fill = TerminalsFilling(grammar)
      to_process = Queue()
      for r in grammar.rules:
          to_process.put(r)
      while not to_process.empty():
          rule = to_process.get()  # type: Type[Rule]
          # Check, if rule must be split
          if len(rule.right) > 2:
              grammar.rules.remove(rule)
              # create nonterm that represent group on the right
              created_nonterm = type("ChomskyGroup[" + rule.__name__ + "]",
                                     (ChomskyGroupNonterminal,),
                                     ChomskyGroupNonterminal.__dict__.copy())  # type: Type[ChomskyGroupNonterminal]
              created_nonterm.group = rule.right[1:]
              # create rule that replace current
              created_left_rule = type("ChomskySplit[" + rule.__name__ + "]",
                                       (ChomskySplitRule,),
                                       ChomskySplitRule.__dict__.copy())  # type: Type[ChomskySplitRule]
              created_left_rule.rule = ([rule.fromSymbol], [rule.right[0], created_nonterm])
              created_left_rule.from_rule = rule
              # create rule with symbols on the right
              created_right_rule = type("ChomskyRest[" + rule.__name__ + "]",
                                        (ChomskyRestRule,),
                                        ChomskyRestRule.__dict__.copy())  # type: Type[ChomskyRestRule]
              created_right_rule.rule = ([created_nonterm], rule.right[1:])
              created_right_rule.from_rule = rule
              # add it to the grammar
              grammar.nonterminals.add(created_nonterm)
              grammar.rules.add(created_left_rule, created_right_rule)
              to_process.put(created_left_rule)
              to_process.put(created_right_rule)
          # check, if must replace terminal
          elif len(rule.right) == 2:
              if rule.right[0] in grammar.terminals:
                  # first symbol is terminal
                  # remove rule from grammar
                  grammar.rules.remove(rule)
                  # get nonterminal rewritable to the terminal and add that rules into the grammar implicitly
                  symb = fill.get(rule.right[0])
                  # create rule replacing the original one
                  created = type("ChomskyLeft[" + rule.__name__ + "]",
                                 (ChomskyTerminalReplaceRule,),
                                 ChomskyTerminalReplaceRule.__dict__.copy())  # type: Type[ChomskyTerminalReplaceRule]
                  created.rule = ([rule.fromSymbol], [symb, rule.right[1]])
                  created.from_rule = rule
                  created.replaced_index = 0
                  # add it into the grammar
                  grammar.rules.add(created)
                  to_process.put(created)
              elif rule.right[1] in grammar.terminals:
                  # second symbol is terminal
                  # remove rule from grammar
                  grammar.rules.remove(rule)
                  # get nonterminal rewritable to the terminal and add that rules into the grammar implicitly
                  symb = fill.get(rule.right[1])
                  # create rule replacing the original one
                  created = type("ChomskyRight[" + rule.__name__ + "]",
                                 (ChomskyTerminalReplaceRule,),
                                 ChomskyTerminalReplaceRule.__dict__.copy())
                  created.rule = ([rule.fromSymbol], [rule.right[0], symb])
                  created.from_rule = rule
                  created.replaced_index = 1
                  # add it into the grammar
                  grammar.rules.add(created)
                  to_process.put(created)
      return grammar