コード例 #1
0
    def __transform(self, ast):

        root_type = type(ast)  # will be AST class for AND or FOLLOWEDBY
        changed = False
        or_children = []
        other_children = []
        for child in ast.operands:
            if isinstance(child, OrObservationExpression):
                or_children.append(child.operands)
            else:
                other_children.append(child)

        if or_children:
            distributed_children = [
                root_type([
                    _dupe_ast(sub_ast) for sub_ast in itertools.chain(
                        other_children,
                        prod_seq,
                    )
                ]) for prod_seq in itertools.product(*or_children)
            ]

            # Need to recursively continue to distribute AND/FOLLOWEDBY over OR
            # in any of our new sub-expressions which need it.
            distributed_children = [
                self.transform(child)[0] for child in distributed_children
            ]

            result = OrObservationExpression(distributed_children)
            changed = True

        else:
            result = ast

        return result, changed
コード例 #2
0
ファイル: observation.py プロジェクト: zv/cti-python-stix2
def _dupe_ast(ast):
    """
    Create a duplicate of the given AST.  The AST root must be an observation
    expression of some kind (AND/OR/qualified, etc).

    Note: the observation expression "leaves", i.e. simple square-bracket
    observation expressions are currently not duplicated.  I don't think it's
    necessary as of this writing.  But revisit this if/when necessary.

    Args:
        ast: The AST to duplicate

    Returns:
        The duplicate AST
    """
    if isinstance(ast, AndObservationExpression):
        result = AndObservationExpression(
            [_dupe_ast(child) for child in ast.operands])

    elif isinstance(ast, OrObservationExpression):
        result = OrObservationExpression(
            [_dupe_ast(child) for child in ast.operands])

    elif isinstance(ast, FollowedByObservationExpression):
        result = FollowedByObservationExpression(
            [_dupe_ast(child) for child in ast.operands])

    elif isinstance(ast, QualifiedObservationExpression):
        # Don't need to dupe the qualifier object at this point
        result = QualifiedObservationExpression(
            _dupe_ast(ast.observation_expression),
            ast.qualifier,
        )

    elif isinstance(ast, ObservationExpression):
        result = ast

    else:
        raise TypeError("Can't duplicate " + type(ast).__name__)

    return result
コード例 #3
0
ファイル: observation.py プロジェクト: zv/cti-python-stix2
    def __transform(self, ast):

        # If no OR children, nothing to do
        if any(
                isinstance(child, OrObservationExpression)
                for child in ast.operands):
            # When we distribute FOLLOWEDBY over OR, it is important to
            # preserve the original FOLLOWEDBY order!  We don't need to do that
            # for AND, but we do it anyway because it doesn't hurt, and we can
            # use the same code for both.
            iterables = []
            for child in ast.operands:
                if isinstance(child, OrObservationExpression):
                    iterables.append(child.operands)
                else:
                    iterables.append((child, ))

            root_type = type(ast)  # will be AST class for AND or FOLLOWEDBY
            distributed_children = [
                root_type([
                    _dupe_ast(sub_ast)
                    for sub_ast in itertools.chain(prod_seq, )
                ]) for prod_seq in itertools.product(*iterables)
            ]

            # Need to recursively continue to distribute AND/FOLLOWEDBY over OR
            # in any of our new sub-expressions which need it.
            distributed_children = [
                self.transform(child)[0] for child in distributed_children
            ]

            result = OrObservationExpression(distributed_children)
            changed = True

        else:
            result = ast
            changed = False

        return result, changed