Esempio n. 1
0
    def deep_find_match_Name(self, ins_node, std_node, check_meta=True):
        name_id = ins_node.astNode.id
        match = _name_regex(name_id)
        mapping = AstMap()
        matched = False
        meta_matched = self.metas_match(ins_node, std_node, check_meta)
        if match[_VAR] and meta_matched:  # if variable
            # This if body is probably unnecessary.
            if type(std_node.astNode).__name__ == "Name":
                return self.deep_find_match_generic(ins_node, std_node,
                                                    check_meta)
        # could else return False, but shallow_match_generic should do this as well
        elif match[_EXP]:  # and meta_matched:  # if expression
            # terminate recursion, the whole subtree should match since expression nodes match to anything
            mapping.add_exp_to_sym_table(ins_node, std_node)
            matched = True
        elif match[_WILD] and meta_matched:  # if wild card, don't care
            # terminate the recursion, the whole subtree should match since wild cards match to anything
            matched = True

        if matched:
            mapping.add_node_pairing(ins_node, std_node)
            return [mapping]
        # else
        return self.deep_find_match_generic(ins_node, std_node, check_meta)
    def deep_find_match_Expr(self, ins_node, std_node, check_meta=True):
        """
        An Expression node (not to be confused with expressions denoted by the instructor nodes in Name ast nodes)
        checks whether it should be generic, or not
        Args:
            ins_node: Instructor ast to find in the student ast
            std_node: Student AST to search for the instructor ast in
            check_meta: flag to check whether the fields of the instructor node and the student node should match

        Returns:
            AstMap: a mapping between the instructor and student asts, or False if such a mapping doesn't exist
        """
        # if check_meta and ins_node.field != std_node.field:
        if not self.metas_match(ins_node, std_node, check_meta):
            return []
        mapping = AstMap()
        value = ins_node.value
        ast_type = type(value.astNode).__name__
        if ast_type == "Name":
            name_id = value.astNode.id
            exp_match = re.compile('^__.*__$')  # /regex
            wild_card = re.compile('^___$')  # /regex
            matched = False
            meta_matched = self.metas_match(ins_node, std_node, check_meta)
            if exp_match.match(name_id):  # and meta_matched:  # if expression
                # terminate recursion, the whole subtree should match since expression nodes match to anything
                mapping.add_exp_to_sym_table(value, std_node)
                matched = True
            elif wild_card.match(name_id) and meta_matched:  # if wild card, don't care
                # terminate the recursion, the whole subtree should match since wild cards match to anything
                matched = True
            if matched:
                mapping.add_node_pairing(ins_node, std_node)
                return [mapping]
        return self.deep_find_match_generic(ins_node, std_node, check_meta)
Esempio n. 3
0
    def shallow_symbol_handler(self,
                               ins_node,
                               std_node,
                               id_val,
                               check_meta=True):
        """
        TODO: Make this handle the func field to handle functions
        Matches ins_node to std_node for different cases of encountering a name node in ins_node
            case 1: _var_ matches if std_node is a name node and automatically returns a mapping and symbol table
            case 2: __exp__ matches to any subtree and automatically returns a mapping and symbol table
            case 3: ___ matches to any subtree and automatically returns a mapping
            case 4: matches only if the exact names are the same (falls through to shallow_match_generic)
        Args:
            ins_node:
            std_node:
            id_val:
            check_meta:

        Returns:
            list of AstMap: a mapping of ins_node to std_node and possibly a symbol_table, or False if it doesn't match
        """
        name_id = ins_node.astNode.__getattribute__(id_val)
        match = _name_regex(name_id)
        mapping = AstMap()
        matched = False
        # TODO: add functionality to add function references to func_table?
        meta_matched = self.metas_match(ins_node, std_node, check_meta)
        if match[_VAR] and meta_matched:  # variable
            if type(std_node.astNode).__name__ == "Name" or id_val == "attr":
                if id_val == "attr":
                    std_node.astNode.id = std_node.astNode.attr
                if std_node.field == "func" and ins_node.field != "none":
                    # TODO: This 'ins_node.field != "none"' code is for an obscure edge case where the instructor code
                    # is only _var_
                    mapping.add_func_to_sym_table(ins_node, std_node)
                else:
                    mapping.add_var_to_sym_table(
                        ins_node, std_node)  # TODO: Capture result?
                matched = True
        # could else return False, but shallow_match_generic should do this as well
        elif match[
                _EXP] and meta_matched:  # expression TODO: In theory this won't run?
            mapping.add_exp_to_sym_table(ins_node, std_node)
            matched = True
        elif match[
                _WILD] and meta_matched:  # don't care TODO: In theory this won't run?
            matched = True

        if matched:
            mapping.add_node_pairing(ins_node, std_node)
            return [mapping]
        # else
        return self.shallow_match_generic(ins_node, std_node, check_meta)
    def shallow_symbol_handler(self, ins_node, std_node, id_val, check_meta=True):
        """
        TODO: Make this handle the func field to handle functions
        Matches ins_node to std_node for different cases of encountering a name node in ins_node
            case 1: _var_ matches if std_node is a name node and automatically returns a mapping and symbol table
            case 2: __exp__ matches to any subtree and automatically returns a mapping and symbol table
            case 3: ___ matches to any subtree and automatically returns a mapping
            case 4: matches only if the exact names are the same (falls through to shallow_match_generic)
        Args:
            ins_node:
            std_node:
            id_val:
            check_meta:

        Returns:
            list of AstMap: a mapping of ins_node to std_node and possibly a symbol_table, or False if it doesn't match
        """
        name_id = ins_node.astNode.__getattribute__(id_val)
        match = _name_regex(name_id)
        mapping = AstMap()
        matched = False
        # TODO: add functionality to add function references to func_table?
        meta_matched = self.metas_match(ins_node, std_node, check_meta)
        if match[_VAR] and meta_matched:  # variable
            if type(std_node.astNode).__name__ == "Name" or id_val in ["attr", "arg"]:
                if id_val in ["attr", "arg"]:
                    std_node.astNode._id = std_node.astNode.__getattribute__(id_val)
                if std_node.field == "func" and ins_node.field != _NONE_FIELD:
                    # TODO: This 'ins_node.field != _NONE_FIELD' code is for an obscure edge case where the
                    #  instructor code is only _var_
                    std_node.astNode._id = std_node.astNode.__getattribute__(id_val)
                    mapping.add_func_to_sym_table(ins_node, std_node)
                else:
                    std_node.astNode._id = std_node.astNode.__getattribute__(id_val)
                    mapping.add_var_to_sym_table(ins_node, std_node)  # TODO: Capture result?
                matched = True
        # could else return False, but shallow_match_generic should do this as well
        elif match[_EXP] and meta_matched:
            mapping.add_exp_to_sym_table(ins_node, std_node)
            matched = True
        elif match[_WILD] and meta_matched:
            matched = True

        if matched:
            mapping.add_node_pairing(ins_node, std_node)
            return [mapping]
        # else
        return self.shallow_match_main(ins_node, std_node, check_meta=check_meta, ignores=["ctx"])
Esempio n. 5
0
    def deep_find_match_Name(self,
                             ins_node,
                             std_node,
                             check_meta=True,
                             use_previous=None):
        """

        Args:
            ins_node:
            std_node:
            check_meta:
            use_previous:

        Returns:

        """
        name_id = ins_node.astNode.id
        match = _name_regex(name_id)
        mapping = AstMap()
        matched = False
        meta_matched = self.metas_match(ins_node, std_node, check_meta)
        if match[_VAR] and meta_matched:  # if variable
            if type(std_node.astNode).__name__ == "Name":
                return self.deep_find_match_generic(ins_node,
                                                    std_node,
                                                    check_meta=check_meta,
                                                    ignores=["ctx"],
                                                    use_previous=use_previous)
        # could else return False, but shallow_match_generic should do this as well
        elif match[_EXP] and meta_matched:  # and meta_matched:  # if expression
            # terminate recursion, the whole subtree should match since expression nodes match to anything
            mapping.merge_map_with(use_previous)
            mapping.add_exp_to_sym_table(ins_node, std_node)
            matched = True
        elif match[_WILD] and meta_matched:  # if wild card, don't care
            # terminate the recursion, the whole subtree should match since wild cards match to anything
            matched = True

        if matched:
            mapping.add_node_pairing(ins_node, std_node)
            return [mapping]
        # else
        return self.deep_find_match_generic(ins_node,
                                            std_node,
                                            check_meta=check_meta,
                                            ignores=["ctx"],
                                            use_previous=use_previous)
Esempio n. 6
0
    def deep_find_match_Expr(self,
                             ins_node,
                             std_node,
                             check_meta=True,
                             use_previous=None):
        """
        An Expression node (not to be confused with expressions denoted by the instructor nodes in Name ast nodes)
        checks whether it should be generic, or not
        Args:
            ins_node: Instructor ast to find in the student ast
            std_node: Student AST to search for the instructor ast in
            check_meta: flag to check whether the fields of the instructor node and the student node should match
            use_previous: An AstMap from a previous matching run

        Returns:
            AstMap: a mapping between the instructor and student asts, or False if such a mapping doesn't exist
        """
        # if check_meta and ins_node.field != std_node.field:
        if not self.metas_match(ins_node, std_node, check_meta):
            return []
        mapping = AstMap() if use_previous is None else use_previous
        value = ins_node.value
        ast_type = type(value.astNode).__name__
        if ast_type == "Name":
            name_id = value.astNode.id
            exp_match = re.compile('^__.*__$')  # /regex
            wild_card = re.compile('^___$')  # /regex
            matched = False
            meta_matched = self.metas_match(ins_node, std_node, check_meta)
            if exp_match.match(
                    name_id
            ) and meta_matched:  # and meta_matched:  # if expression
                # terminate recursion, the whole subtree should match since expression nodes match to anything
                mapping.add_exp_to_sym_table(value, std_node)
                matched = True
            elif wild_card.match(
                    name_id) and meta_matched:  # if wild card, don't care
                # terminate the recursion, the whole subtree should match since wild cards match to anything
                matched = True
            if matched:
                mapping.add_node_pairing(ins_node, std_node)
                return [mapping]
        return self.deep_find_match_generic(ins_node, std_node, check_meta)
    def deep_find_match_Name(self, ins_node, std_node, check_meta=True):
        name_id = ins_node.astNode.id
        match = _name_regex(name_id)
        mapping = AstMap()
        matched = False
        meta_matched = self.metas_match(ins_node, std_node, check_meta)
        if match[_VAR] and meta_matched:  # if variable
            # This if body is probably unnecessary.
            if type(std_node.astNode).__name__ == "Name":
                return self.deep_find_match_generic(ins_node, std_node, check_meta=check_meta, ignores=["ctx"])
        # could else return False, but shallow_match_generic should do this as well
        elif match[_EXP]:  # and meta_matched:  # if expression
            # terminate recursion, the whole subtree should match since expression nodes match to anything
            mapping.add_exp_to_sym_table(ins_node, std_node)
            matched = True
        elif match[_WILD] and meta_matched:  # if wild card, don't care
            # terminate the recursion, the whole subtree should match since wild cards match to anything
            matched = True

        if matched:
            mapping.add_node_pairing(ins_node, std_node)
            return [mapping]
        # else
        return self.deep_find_match_generic(ins_node, std_node, check_meta=check_meta, ignores=["ctx"])