如何从 C 头文件中提取和映射函数名称及其注释?

问题描述 投票:0回答:0

我有许多不同格式的 .h 文件。它们包括函数定义、变量定义等。我的目标是提取所有函数名称及其各自的注释并映射它们。 我正在寻找一种使用 Python 来完成此操作的工作方法。 我尝试了以下方法:

pycparser

https://github.com/eliben/pycparser

我阅读了以下关于我的问题的博客文章,但我无法让它工作: https://eli.thegreenplace.net/2015/on-parsing-c-type-declarations-and-fake-headers

使用下面的代码我得到以下错误:

pycparser.plyparser.ParseError: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/i386/_types.h:100:27: before: __darwin_va_list

import sys
from pycparser import parse_file

sys.path.extend(['.', '..'])

if __name__ == "__main__":
    filename = "<pathToHeader>/file.h"

    ast = parse_file(filename, use_cpp=True,
            cpp_path='gcc',
            cpp_args=['-E', r'<pathToPycparser>/utils/fake_libc_include'])
    ast.show()

图书馆

https://pyclibrary.readthedocs.io/en/latest/

这实际上运行没有错误,但是它没有在示例文件中找到任何函数。

from pyclibrary import CParser
parser = CParser(["<pathToHeader>/file.h")])
print(parser)

pygccxml

https://pygccxml.readthedocs.io/en/master/index.html

运行下面的代码,我得到了很多错误,例如unknown type name 'NSString 并且脚本在 20 个错误后停止,因为发出了太多错误。

from pygccxml import utils
from pygccxml import declarations
from pygccxml import parser

generator_path, generator_name = utils.find_xml_generator()

xml_generator_config = parser.xml_generator_configuration_t(
    xml_generator_path=generator_path,
    xml_generator=generator_name)

filename = "<pathToHeader>/file.h"

decls = parser.parse([filename], xml_generator_config)

global_namespace = declarations.get_global_namespace(decls)

ns = global_namespace.namespace("ns")

氧气

https://www.doxygen.nl/index.html

尽管 Doxygen 本身不是一个解析器,而是一个代码文档工具,但我用它得到了最好的结果。它创建一个包含所有函数名称(甚至正确解析)以及注释的 xml 输出。评论被标记为评论,甚至用行号注明。但是,函数并没有标注行号,所以将正确的注释匹配到正确的函数基本上是不可能的。

自定义解析器

我自己创建了一个简单的解析器,它以某种方式工作,但我不能确定我涵盖了这些文件中使用的所有可能的 C 语法,因为文件中使用了不同的语法,我无法手动检查所有文件的语法因为太多了。

functionComments = {}
inComment = False
comment = []
function = None

for i in range(0, len(lines)):

    line = lines[i].strip()

    if line.startswith("/*"):
        inComment = True

    elif line.endswith("*/"):
        inComment = False
        comment.append(line[:-2].strip())

        if len(lines) > i+1 and lines[i+1].startswith("- ("):
            functionName = lines[i+1]
            counter = 2

            while len(lines) > i+counter and lines[i+counter] != "\n":
                functionName += " " + lines[i+counter].lstrip().split(" API_")[0]
                counter += 1

            if ":" in functionName:
                functionNameParts = functionName.split(":")
                functionNamePartsSplitBySpace = []
                function = ""

                for j in range(0, len(functionNameParts)-1):
                    functionNamePartsSplitBySpace.append(functionNameParts[j].split(" "))

                for k in range(0, len(functionNamePartsSplitBySpace)):
                    function += functionNamePartsSplitBySpace[k][-1].split(")")[-1] + ":"

            else:
                function = lines[i+1].split(" NS_AVAILABLE")[0].split(")")[-1]

            functionComments[function] = "\n".join(comment)
            comment = []
            function = None

        else:
            function = None
            comment = []

    elif inComment:

        if line.startswith("* "):
            comment.append(line[2:].strip())

        else:
            comment.append(line)
python c header-files doxygen pycparser
© www.soinside.com 2019 - 2024. All rights reserved.