示例#1
0
def create_snippet(parent, children, choice, key):
    """
    Given a parent NT and a list of child trees, create a new tree that acts as
    the parent of the given children. Generates this tree as a snippet and
    adds the new snippet to the trackers.snippets library.

    :param parent: A non-terminal root.
    :param children: A list of derivation tree instances.
    :param choice: The chosen production choice.
    :param key: A new key for the trackers.snippets dictionary.
    :return: Nothing.
    """

    # Initialise new instance of the tree class to act as new snippet.
    new_tree = tree.Tree(parent, None)

    # Generate a codon to match the given production choice.
    new_tree.codon = generate_codon(parent, choice)

    # Save the snippet key of this tree.
    new_tree.snippet = key

    # Add the children to the new node
    for child in children:
        new_tree.children.append(child)

        # Set the parent of the child to the new node
        child.parent = new_tree

    # Add new snippet to snippets dictionary
    trackers.snippets[key] = new_tree
示例#2
0
                        def check_reductions(alt_cs, pre, aft, idx, children):
                            """
                            Given a list of the indexes of potential children, find
                            snippets which match adjacent portions of the target
                            string that can be used as these children.
    
                            :param alt_cs: An ordered list of indexes of
                            potential Terminals or Non Terminals to
                            reduce_trees.
                            :param pre: The start index of the overall snippet
                            on the target string.
                            :param aft: The end index of the overall snippet on
                            the target string.
                            :param children: A list of children to be reduced.
                            :param idx: The index of the current child.
                            :return: The same inputs, in the same order.
                            """

                            if idx < len(alt_cs):

                                # Take the next available unexpanded item from the
                                # list.
                                child_idx = alt_cs[idx]
                                child = NTs[child_idx]

                                # Increment counter.
                                idx += 1

                                if pre is None:
                                    # Then we are starting with an NT which
                                    # directly follows the current NT.

                                    if child[1] == "T":
                                        # Then we can immediately check if this
                                        # reduction T is legally allowed
                                        # follow the current NT in the target
                                        # string.

                                        # Get output to check for match.
                                        check = child[0]

                                        # Get portion of target string to match.
                                        end_point = aft + len(check)

                                        target = params['TARGET'][
                                            aft:end_point]

                                        if target == check:
                                            # The current terminal matches the same
                                            # location on the target string.

                                            # Generate fake key for snippets dict.
                                            key = str([aft, end_point])

                                            # Increment aft phenotype counter.
                                            aft += len(check)

                                            # Create new tree from this terminal.
                                            T_tree = tree.Tree(check, None)

                                            # Add to children.
                                            children[child_idx] = [key, T_tree]

                                            if alt_cs:
                                                # Recurse to find the next piece of
                                                # the puzzle.
                                                check_reductions(
                                                    alt_cs, pre, aft, idx,
                                                    children)

                                    elif child[1] == "NT":
                                        # Check to see if there are any snippets
                                        # which can be reduced to the current
                                        # block.

                                        # Find all potential snippets which
                                        # match our criteria.
                                        matches = [
                                            v for v in sorted_keys if
                                            v[0][0] == aft and v[1] == child[0]
                                        ]

                                        # Create a copy of this marker otherwise
                                        # each match will over-write it.
                                        aft_c = copy(aft)

                                        for match in matches:
                                            # Iterate over all potential matches.

                                            # Calculate length of match string.
                                            str_len = match[0]

                                            # Increment appropriate phenotype
                                            # counter.
                                            aft_c = aft + str_len[1] - str_len[
                                                0]

                                            # Add to children.
                                            children[child_idx] = [
                                                match[2],
                                                trackers.snippets[match[2]]
                                            ]

                                            if alt_cs:
                                                # Recurse to find the next piece of
                                                # the puzzle.
                                                check_reductions(
                                                    alt_cs, pre, aft_c, idx,
                                                    children)

                                elif aft is None:
                                    # Then we are starting with an NT which
                                    # directly precedes the current NT.

                                    if child[1] == "T":
                                        # Then we can immediately check if this
                                        # reduction T is legally allowed
                                        # follow the current NT in the target
                                        # string.

                                        # Get output to check for match.
                                        check = child[0]

                                        # Get portion of target string to match.
                                        start_point = pre - len(check)

                                        target = params['TARGET'][
                                            start_point:pre]

                                        if target == check:
                                            # The current terminal matches the same
                                            # location on the target string.

                                            # Generate fake key for snippets dict.
                                            key = str([start_point, pre])

                                            # Increment pre phenotype counter.
                                            pre -= len(check)

                                            # Create new tree from this terminal.
                                            T_tree = tree.Tree(check, None)

                                            # Add to children.
                                            children[child_idx] = [key, T_tree]

                                            if alt_cs:
                                                # Recurse to find the next piece of
                                                # the puzzle.
                                                check_reductions(
                                                    alt_cs, pre, aft, idx,
                                                    children)

                                    elif child[1] == "NT":
                                        # Check to see if there are any snippets
                                        # which can be reduced to the current
                                        # block.

                                        # Find all potential snippets which
                                        # match our criteria.
                                        matches = [
                                            v for v in sorted_keys if
                                            v[0][1] == pre and v[1] == child[0]
                                        ]

                                        # Create a copy of this marker otherwise
                                        # each match will over-write it.
                                        pre_c = copy(pre)

                                        for match in matches:
                                            # Iterate over all potential matches.

                                            # Calculate length of match string.
                                            str_len = match[0]

                                            # Increment appropriate phenotype
                                            # counter.
                                            pre_c = pre - str_len[1] + str_len[
                                                0]

                                            # Add to children.
                                            children[child_idx] = [
                                                match[2],
                                                trackers.snippets[match[2]]
                                            ]

                                            if alt_cs:
                                                # Recurse to find the next piece of
                                                # the puzzle.
                                                check_reductions(
                                                    alt_cs, pre_c, aft, idx,
                                                    children)

                                else:
                                    # Our starting NT is somewhere in the middle
                                    # of the proposed reduction.

                                    if child[1] == "T":
                                        # Then we can immediately check if this
                                        # reduction T is legally allowed be
                                        # where it wants to be.

                                        # Get output to check for match.
                                        check = child[0]

                                        # Get portion of target string to match.
                                        if child_idx > loc:
                                            # This T comes after the original NT.
                                            start_point = aft
                                            end_point = start_point + len(
                                                check)

                                        else:
                                            # This T comes before the original NT.
                                            start_point = pre - len(check)
                                            end_point = pre

                                        target = params['TARGET'][
                                            start_point:end_point]

                                        if target == check:
                                            # The current terminal matches the same
                                            # location on the target string.

                                            # Increment appropriate phenotype
                                            # counter.
                                            if child_idx > loc:
                                                # This T comes after the original
                                                # NT.
                                                aft += len(check)

                                            else:
                                                # This T comes before the original
                                                # NT.
                                                pre -= len(check)

                                            # Generate fake key for snippets dict.
                                            key = str([start_point, end_point])

                                            # Create new tree from this terminal.
                                            T_tree = tree.Tree(check, None)

                                            # Add to children.
                                            children[child_idx] = [key, T_tree]

                                            if alt_cs:
                                                # Recurse to find the next piece of
                                                # the puzzle.
                                                check_reductions(
                                                    alt_cs, pre, aft, idx,
                                                    children)

                                    elif child[1] == "NT":
                                        # Check to see if there are any snippets
                                        # which can be reduced to the current
                                        # block.

                                        # Get portion of target string to match.
                                        if child_idx > loc:
                                            # This NT comes after the original NT.
                                            matches = [
                                                v for v in sorted_keys
                                                if v[0][0] == aft
                                                and v[1] == child[0]
                                            ]

                                        else:
                                            # This NT comes before the original NT.
                                            matches = [
                                                v for v in sorted_keys
                                                if v[0][1] == pre
                                                and v[1] == child[0]
                                            ]

                                        # Create copies of this markers otherwise
                                        # each match will over-write them.
                                        pre_c, aft_c = copy(pre), copy(aft)

                                        for match in matches:
                                            # Iterate over all potential matches.

                                            # Calculate length of match string.
                                            str_len = match[0]

                                            # Increment appropriate phenotype
                                            # counter.
                                            if child_idx > loc:
                                                # This NT comes after the original
                                                # NT.
                                                aft_c = aft + str_len[
                                                    1] - str_len[0]

                                            else:
                                                # This NT comes before the original
                                                # NT.
                                                pre_c = pre - str_len[
                                                    1] + str_len[0]

                                            # Add to children.
                                            children[child_idx] = [
                                                match[2],
                                                trackers.snippets[match[2]]
                                            ]

                                            if alt_cs:
                                                # Recurse to find the next piece of
                                                # the puzzle.
                                                check_reductions(
                                                    alt_cs, pre_c, aft_c, idx,
                                                    children)

                            elif all([i != [] for i in children]):
                                # We have compiled a full set of potneital
                                # children to reduce_trees. Generate a key and check
                                # if it exists.
                                generate_key_and_check(pre, aft, reduce,
                                                       children)