(node, parent=None)
return new_node
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*).
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*).
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 * ) .
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
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 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