class_docstr: Compiles a grammar. This will take the parse tree of a regular expression
  and compile the grammar.
  
  :param root_node: :class~`.regex_parser.Node` instance.
  :param escape_funcs: `dict` mapping variable names to escape callables.
  :param unescape_funcs: `dict` mapping variable names to unescape callables.
class_docstr_tok: ["Compiles","a","grammar",".","This","will","take","the","parse","tree","of","a","regular","expression","and","compile","the","grammar",".",":","param","root_node",":",":","class~","`",".regex_parser.Node","`","instance",".",":","param","escape_funcs",":","`","dict","`","mapping","variable","names","to","escape","callables",".",":","param","unescape_funcs",":","`","dict","`","mapping","variable","names","to","unescape","callables","."]
docstr: Yield all the regular expressions matching a prefix of the grammar
  defined by the `Node` instance.
  
  For each `Variable`, one regex pattern will be generated, with this
  named group at the end. This is required because a regex engine will
  terminate once a match is found. For autocompletion however, we need
  the matches for all possible paths, so that we can provide completions
  for each `Variable`.
  
  - So, in the case of an `Any` (`A|B|C)', we generate a pattern for each
    clause. This is one for `A`, one for `B` and one for `C`. Unless some
    groups don't contain a `Variable`, then these can be merged together.
  - In the case of a `NodeSequence` (`ABC`), we generate a pattern for
    each prefix that ends with a variable, and one pattern for the whole
    sequence. So, that's one for `A`, one for `AB` and one for `ABC`.
  
  :param root_node: The :class:`Node` instance for which we generate the grammar.
  :param create_group_func: A callable which takes a `Node` and returns the next
      free name for this node.
docstr_tok: ["Yield","all","the","regular","expressions","matching","a","prefix","of","the","grammar","defined","by","the","`","Node","`","instance",".","For","each","`","Variable","`",",","one","regex","pattern","will","be","generated",",","with","this","named","group","at","the","end",".","This","is","required","because","a","regex","engine","will","terminate","once","a","match","is","found",".","For","autocompletion","however",",","we","need","the","matches","for","all","possible","paths",",","so","that","we","can","provide","completions","for","each","`","Variable","`",".","-","So",",","in","the","case","of","an","`","Any","`","(","`","A|B|C",")","'",",","we","generate","a","pattern","for","each","clause",".","This","is","one","for","`","A","`",",","one","for","`","B","`","and","one","for","`","C","`",".","Unless","some","groups","do","n't","contain","a","`","Variable","`",",","then","these","can","be","merged","together",".","-","In","the","case","of","a","`","NodeSequence","`","(","`","ABC","`",")",",","we","generate","a","pattern","for","each","prefix","that","ends","with","a","variable",",","and","one","pattern","for","the","whole","sequence",".","So",",","that","'s","one","for","`","A","`",",","one","for","`","AB","`","and","one","for","`","ABC","`",".",":","param","root_node",":","The",":","class",":","`","Node","`","instance","for","which","we","generate","the","grammar",".",":","param","create_group_func",":","A","callable","which","takes","a","`","Node","`","and","returns","the","next","free","name","for","this","node","."]
code: def _transform_prefix(
      cls, root_node: Node, create_group_func: Callable[[Variable], str]
  ) -> Iterable[str]:
      """
      Yield all the regular expressions matching a prefix of the grammar
      defined by the `Node` instance.
  
      For each `Variable`, one regex pattern will be generated, with this
      named group at the end. This is required because a regex engine will
      terminate once a match is found. For autocompletion however, we need
      the matches for all possible paths, so that we can provide completions
      for each `Variable`.
  
      - So, in the case of an `Any` (`A|B|C)', we generate a pattern for each
        clause. This is one for `A`, one for `B` and one for `C`. Unless some
        groups don't contain a `Variable`, then these can be merged together.
      - In the case of a `NodeSequence` (`ABC`), we generate a pattern for
        each prefix that ends with a variable, and one pattern for the whole
        sequence. So, that's one for `A`, one for `AB` and one for `ABC`.
  
      :param root_node: The :class:`Node` instance for which we generate the grammar.
      :param create_group_func: A callable which takes a `Node` and returns the next
          free name for this node.
      """
  
      def contains_variable(node: Node) -> bool:
          if isinstance(node, Regex):
              return False
          elif isinstance(node, Variable):
              return True
          elif isinstance(node, (Lookahead, Repeat)):
              return contains_variable(node.childnode)
          elif isinstance(node, (NodeSequence, AnyNode)):
              return any(
                  contains_variable(child) for child in node.children
              )
  
          return False
  
      def transform(node: Node) -> Iterable[str]:
          # Generate separate pattern for all terms that contain variables
          # within this OR. Terms that don't contain a variable can be merged
          # together in one pattern.
          if isinstance(node, AnyNode):
              # If we have a definition like:
              #           (?P<name> .*)  | (?P<city> .*)
              # Then we want to be able to generate completions for both the
              # name as well as the city. We do this by yielding two
              # different regular expressions, because the engine won't
              # follow multiple paths, if multiple are possible.
              children_with_variable = []
              children_without_variable = []
              for c in node.children:
                  if contains_variable(c):
                      children_with_variable.append(c)
                  else:
                      children_without_variable.append(c)
  
              for c in children_with_variable:
                  yield from transform(c)
  
              # Merge options without variable together.
              if children_without_variable:
                  yield "|".join(
                      r
                      for c in children_without_variable
                      for r in transform(c)
                  )
  
          # For a sequence, generate a pattern for each prefix that ends with
          # a variable + one pattern of the complete sequence.
          # (This is because, for autocompletion, we match the text before
          # the cursor, and completions are given for the variable that we
          # match right before the cursor.)
          elif isinstance(node, NodeSequence):
              # For all components in the sequence, compute prefix patterns,
              # as well as full patterns.
              complete = [
                  cls._transform(c, create_group_func)
                  for c in node.children
              ]
              prefixes = [list(transform(c)) for c in node.children]
              variable_nodes = [
                  contains_variable(c) for c in node.children
              ]
  
              # If any child is contains a variable, we should yield a
              # pattern up to that point, so that we are sure this will be
              # matched.
              for i in range(len(node.children)):
                  if variable_nodes[i]:
                      for c_str in prefixes[i]:
                          yield "".join(complete[:i]) + c_str
  
              # If there are non-variable nodes, merge all the prefixes into
              # one pattern. If the input is: "[part1] [part2] [part3]", then
              # this gets compiled into:
              #  (complete1 + (complete2 + (complete3  | partial3) | partial2) | partial1 )
              # For nodes that contain a variable, we skip the "|partial"
              # part here, because thees are matched with the previous
              # patterns.
              if not all(variable_nodes):
                  result = []
  
                  # Start with complete patterns.
                  for i in range(len(node.children)):
                      result.append("(?:")
                      result.append(complete[i])
  
                  # Add prefix patterns.
                  for i in range(len(node.children) - 1, -1, -1):
                      if variable_nodes[i]:
                          # No need to yield a prefix for this one, we did
                          # the variable prefixes earlier.
                          result.append(")")
                      else:
                          result.append("|(?:")
                          # If this yields multiple, we should yield all combinations.
                          assert len(prefixes[i]) == 1
                          result.append(prefixes[i][0])
                          result.append("))")
  
                  yield "".join(result)
  
          elif isinstance(node, Regex):
              yield "(?:%s)?" % node.regex
  
          elif isinstance(node, Lookahead):
              if node.negative:
                  yield "(?!%s)" % cls._transform(
                      node.childnode, create_group_func
                  )
              else:
                  # Not sure what the correct semantics are in this case.
                  # (Probably it's not worth implementing this.)
                  raise Exception(
                      "Positive lookahead not yet supported."
                  )
  
          elif isinstance(node, Variable):
              # (Note that we should not append a '?' here. the 'transform'
              # method will already recursively do that.)
              for c_str in transform(node.childnode):
                  yield f"(?P<{create_group_func(node)}>{c_str})"
  
          elif isinstance(node, Repeat):
              # If we have a repetition of 8 times. That would mean that the
              # current input could have for instance 7 times a complete
              # match, followed by a partial match.
              prefix = cls._transform(node.childnode, create_group_func)
  
              if node.max_repeat == 1:
                  yield from transform(node.childnode)
              else:
                  for c_str in transform(node.childnode):
                      if node.max_repeat:
                          repeat_sign = "{,%i}" % (node.max_repeat - 1)
                      else:
                          repeat_sign = "*"
                      yield "(?:{}){}{}{}".format(
                          prefix,
                          repeat_sign,
                          ("" if node.greedy else "?"),
                          c_str,
                      )
  
          else:
              raise TypeError("Got %r" % node)
  
      for r in transform(root_node):
          yield "^(?:%s)$" % r
  
imports: from __future__ import annotations
  import re
  from typing import Callable, Dict, Iterable, Iterator, Pattern
  from typing import Match
  from .regex_parser import AnyNode, Lookahead, Node, NodeSequence, Regex, Repeat, Variable, parse_regex, tokenize_regex
label_desc: Use image node_id 5 for calling the _CompiledGrammar obj's underlying member method code with example usage: obj._transform_prefix(cls, root_node, create_group_func) and returns: False, False, True, contains_variable, any