Example #1
0
 def find(self, string):
     if self.struct:
         class_or_struct = "struct"
     else:
         class_or_struct = "class"
     class_match = re.search(
         class_or_struct + "\s+" + self.name + "(?:\s*:\s*(?P<inherited_classes>[:\w,\s]+))?\s*\{", string
     )
     if class_match is None:
         raise Exception("Cannot find class")
     else:
         start = class_match.end()
         end, output = parse_brackets(string[(start - 1) :])
         return (start, end + start - 1)
Example #2
0
    def parse_header(self, string):
        self.code = string
        access = "private"
        string_split = re.split("((?:public|private|protected)\s*:)+", string)
        access_re = re.compile("(?:(public|private|protected)\s*:)+")
        class_re = re.compile(
            "(?:template\s*\<\s*(?:class|typename)\s+(?P<template_type>[\w+])\s*\>)?(?P<class_or_struct>class|struct)\s+(?P<class_name>\w+)(?:\s*:\s*(?P<inherited_classes>[:\w,\s]+))?\s*\{"
        )
        # regular expression to match class methods in the form <return type> <method_name>(<method_arguments>) [<const>] [<implemented>]
        method_re = re.compile(
            "(?:(?:template\s*\<\s*(?:class|typename)\s+(?P<template_type>[\w]+)\s*\>)|(?:(?P<virtual>virtual)[ \t\f\v]*)|(?:(?P<static>static)[ \t\f\v]*))?(?:(?P<method_const_return_type>const)[ \t\f\v]*)?(?:[ \t\f\v]*(?P<method_return_type>[<>^:\w&* \t\f\v]+?[&*\s]+))(?P<method_name>\w+[,()\s\w~*+=/*^!<>\[\]|&%-]*)\s*\((?P<method_arguments>(?:[\w=\"'.&\s*:\[\]]+\s*,?\s*)*)\)\s*(?P<const>const)?\s*(?P<implemented>{)?"
        )
        # regular expression to match special class methods such as constructor and destructor
        special_method_re = re.compile(
            "(?P<method_name>~?"
            + self.name
            + ")\s*\((?P<method_arguments>(?:[\w&\s*:]+[\[\]\w]+\s*,?\s*)*)\)\s*(?P<implemented>{)?"
        )
        for string in string_split:
            match = access_re.search(string)
            if match is not None:
                access = match.group(1)
                continue
            while True:
                class_match = class_re.search(string)
                if class_match is None:
                    break
                class_or_struct = class_match.group("class_or_struct")
                struct = False
                if class_or_struct == "struct":
                    struct = True
                class_name = class_match.group("class_name")
                inherited_classes = []
                if class_match.group("inherited_classes"):
                    inherited_classes = [i.strip() for i in class_match.group("inherited_classes").split(",")]
                start = class_match.end() - 1
                end, output = parse_brackets(string[start:])
                string = string[: class_match.start()] + string[end:]
                cpp_class = CppClass(class_name, inherited_classes, struct, self)
                cpp_class.parse_header(output)
                if class_match.group("template_type") is not None:
                    cpp_class.templated = True
                    cpp_class.template_type = class_match.group("template_type")
                self.classes[access].append(cpp_class)

            method_matches = method_re.finditer(string)
            for match in method_matches:
                method_name = match.group("method_name")
                method_name = method_name.strip()
                method_return_type = match.group("method_return_type")
                if method_return_type is not None:
                    method_return_type = method_return_type.strip()
                # deal with the regular incorrectly matching a constructor
                if method_return_type == "":
                    continue
                method_arguments = []
                for argument in clean_string(match.group("method_arguments")).split(","):
                    # deal with default arguments
                    if "=" in argument:
                        argument = argument[argument.find("=") - 1]
                    method_arguments.append(argument.strip())
                cpp_method = CppMethod(method_name, method_arguments, method_return_type, self)
                if match.group("virtual") is not None:
                    cpp_method.virtual = True
                if match.group("implemented") is not None:
                    cpp_method.implemented = True
                if match.group("const") is not None:
                    cpp_method.const = True
                if match.group("template_type") is not None:
                    cpp_method.templated = True
                    cpp_method.template_type = match.group("template_type")
                if match.group("method_const_return_type") is not None:
                    cpp_method.const_return_type = True
                if match.group("static") is not None:
                    cpp_method.static = True
                self.methods[access].append(cpp_method)

            special_method_matches = special_method_re.finditer(string)
            for match in special_method_matches:
                method_name = match.group("method_name")
                method_name = method_name.strip()
                method_arguments = [i.strip() for i in match.group("method_arguments").split(",")]
                cpp_method = CppMethod(method_name, method_arguments, parent=self)
                if match.group("implemented") is not None:
                    cpp_method.implemented = True
                self.methods[access].append(cpp_method)