parameters: (node, parent=None)
return_statement: return new_node
docstring: 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*).
docstring_summary: 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*).
docstring_tokens: 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 * ) .
function: 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 occurence 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
function_tokens: def reduce_tree ( node , parent = None ) : 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 occurence 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