Пример #1
0
def move_nodes(nodes, new_parent, in_place=True, remove_empty=True, remove_trivial_unary=True):
    if not in_place:
        nodes = pstree.clone_and_find(nodes + [new_parent])
        new_parent = nodes[-1]
        nodes = nodes[:-1]

    # Find the insertion point in the new parent's subtrees
    old_parent = nodes[0].parent
    nodes.sort(key=lambda x: x.span)
    node_span = (nodes[0].span[0], nodes[-1].span[1])
    insertion_point = 0
    if new_parent.subtrees[0].span[0] == node_span[1]:
        # Inserting before all that are there currently
        pass
    elif new_parent.subtrees[0].span[0] == node_span[0]:
        # Inserting before all that are there currently
        pass
    else:
        for subtree in new_parent.subtrees:
            if subtree.span[0] == node_span[1]:
                break
            insertion_point += 1
            if subtree.span[1] == node_span[0]:
                break
        if insertion_point > len(new_parent.subtrees):
            return (False, "new_parent did not have suitable insertion point")

    # Move the nodes across
    for node in nodes:
        node.parent.subtrees.remove(node)
        new_parent.subtrees.insert(insertion_point, node)
        node.parent = new_parent
        insertion_point += 1

    # If the nodes left behind are empty, remove them
    to_check_for_unary = old_parent
    if remove_empty and len(old_parent.subtrees) == 0:
        to_remove = old_parent
        while len(to_remove.parent.subtrees) == 1:
            to_remove = to_remove.parent
        to_remove.parent.remove(to_remove)

        # If the removal applies, then we will need to check at that level for
        # unaries, rather than down at the old_parent
        to_check_for_unary = to_remove.parent

    # Remove trivial unaries
    if remove_trivial_unary:
        to_check = to_check_for_unary
        if len(to_check.subtrees) == 1 and to_check.label == to_check.subtrees[0].label:
            to_check.subtrees = to_check.subtrees[0].subtrees
            for subtree in to_check.subtrees:
                subtree.parent = to_check

    new_parent.root().calculate_spans()

    return (True, (new_parent.root(), nodes, new_parent))
Пример #2
0
def remove_node_by_node(node, in_place):
    if not in_place:
        node = pstree.clone_and_find(node)
    parent = node.parent
    position = parent.subtrees.index(node)
    init_position = position
    parent.subtrees.pop(position)
    for subtree in node.subtrees:
        subtree.parent = parent
        parent.subtrees.insert(position, subtree)
        position += 1
    return (True, (parent, node, init_position, position))
Пример #3
0
def change_label_by_node(node, new_label, in_place):
    if not in_place:
        node = pstree.clone_and_find(node)
    node.label = new_label
    return (True, (node.root(), node))