code: def reduce_tree(node, parent=None):
      """
      Internal function. Reduces a compiled pattern tree to an
      intermediate representation suitable for feeding the
      automaton. This also trims off any optional pattern elements(like
      [a], a*).
      """
  
      new_node = None
      # switch on the node type
      if node.type == syms.Matcher:
          # skip
          node = node.children[0]
  
      if node.type == syms.Alternatives:
          # 2 cases
          if len(node.children) <= 2:
              # just a single 'Alternative', skip this node
              new_node = reduce_tree(node.children[0], parent)
          else:
              # real alternatives
              new_node = MinNode(type=TYPE_ALTERNATIVES)
              # skip odd children('|' tokens)
              for child in node.children:
                  if node.children.index(child) % 2:
                      continue
                  reduced = reduce_tree(child, new_node)
                  if reduced is not None:
                      new_node.children.append(reduced)
      elif node.type == syms.Alternative:
          if len(node.children) > 1:
              new_node = MinNode(type=TYPE_GROUP)
              for child in node.children:
                  reduced = reduce_tree(child, new_node)
                  if reduced:
                      new_node.children.append(reduced)
              if not new_node.children:
                  # delete the group if all of the children were reduced to None
                  new_node = None
  
          else:
              new_node = reduce_tree(node.children[0], parent)
  
      elif node.type == syms.Unit:
          if (
              isinstance(node.children[0], pytree.Leaf)
              and node.children[0].value == "("
          ):
              # skip parentheses
              return reduce_tree(node.children[1], parent)
          if (
              isinstance(node.children[0], pytree.Leaf)
              and node.children[0].value == "["
          ) or (
              len(node.children) > 1
              and hasattr(node.children[1], "value")
              and node.children[1].value == "["
          ):
              # skip whole unit if its optional
              return None
  
          leaf = True
          details_node = None
          alternatives_node = None
          has_repeater = False
          repeater_node = None
          has_variable_name = False
  
          for child in node.children:
              if child.type == syms.Details:
                  leaf = False
                  details_node = child
              elif child.type == syms.Repeater:
                  has_repeater = True
                  repeater_node = child
              elif child.type == syms.Alternatives:
                  alternatives_node = child
              if (
                  hasattr(child, "value") and child.value == "="
              ):  # variable name
                  has_variable_name = True
  
          # skip variable name
          if has_variable_name:
              # skip variable name, '='
              name_leaf = node.children[2]
              if hasattr(name_leaf, "value") and name_leaf.value == "(":
                  # skip parenthesis
                  name_leaf = node.children[3]
          else:
              name_leaf = node.children[0]
  
          # set node type
          if name_leaf.type == token_labels.NAME:
              # (python) non-name or wildcard
              if name_leaf.value == "any":
                  new_node = MinNode(type=TYPE_ANY)
              else:
                  if hasattr(token_labels, name_leaf.value):
                      new_node = MinNode(
                          type=getattr(token_labels, name_leaf.value)
                      )
                  else:
                      new_node = MinNode(
                          type=getattr(pysyms, name_leaf.value)
                      )
  
          elif name_leaf.type == token_labels.STRING:
              # (python) name or character; remove the apostrophes from
              # the string value
              name = name_leaf.value.strip("'")
              if name in tokens:
                  new_node = MinNode(type=tokens[name])
              else:
                  new_node = MinNode(type=token_labels.NAME, name=name)
          elif name_leaf.type == syms.Alternatives:
              new_node = reduce_tree(alternatives_node, parent)
  
          # handle repeaters
          if has_repeater:
              if repeater_node.children[0].value == "*":
                  # reduce to None
                  new_node = None
              elif repeater_node.children[0].value == "+":
                  # reduce to a single occurrence i.e. do nothing
                  pass
              else:
                  # TODO: handle {min, max} repeaters
                  raise NotImplementedError
                  pass
  
          # add children
          if details_node and new_node is not None:
              for child in details_node.children[1:-1]:
                  # skip '<', '>' markers
                  reduced = reduce_tree(child, new_node)
                  if reduced is not None:
                      new_node.children.append(reduced)
      if new_node:
          new_node.parent = parent
      return new_node
  
file_path: catboost/contrib/tools/python/src/Lib/lib2to3/btm_utils.py
imports: from .None import pytree
  from .pgen2 import grammar, token
  from .pygram import pattern_symbols, python_symbols
label_desc: Use image node_id 1 for calling a global function with example usage: reduce_tree(node, parent) and returns: new_node, reduce_tree, None