如何在Python中解析C++源代码?

14
我们希望解析我们庞大的C++源代码树,以获取足够的信息以供另一个工具制作类和对象关系图、识别整体组织等。 我们目前最好的尝试是运行Python脚本扫描所有.cpp和.h文件,并运行正则表达式搜索来检测类声明、方法等。 我们不需要完整的分析器来捕获每个细节或某些沉重的UML图生成器 - 有很多细节我们想要忽略并且我们正在发明新类型的图表。 这个脚本有点可行,但话说回来:C++确实难以解析!
所以我想知道有哪些从我们的源代码中提取所需信息的工具? 我不是语言专家,也不想使用学习曲线陡峭的工具。 希望我们这些低端程序员可以使用的工具 :P
Python是首选之一,但不是必需的。

6
C++ 非常难解析,通常需要一些比较重的工具来实现(例如 GLR 解析器)。如果有不使用强大解析器的 C++ 解析近似方法,我会非常惊讶。 - templatetypedef
7
你有没有考虑使用GCC-XML(http://www.gccxml.org)以及Python来处理生成的XML文件? - 6502
4
据说世界上只有三种完整的C++解析器,它们分别是GCC的解析器、EDG的解析器,以及可能是微软的解析器(微软可能正在使用EDG)。LLVM的开发人员正在研究一种解析器,但目前还没有完成。从以上信息可以看出需要投入大量的工作量。此外,这里有人(我忘了是谁)声称在他的公司中有一种解析器,但我无法评估该声明的真实性。不幸的是,以上任何一种解析器都不是用Python编写的。虽然EDG的解析器设计成易于连接到新的消费者,但其许可证并不便宜。 - zwol
1
@DarenW:这取决于你当前的工具失败了多少以及为什么失败。如果你能确定失败和原因,那么你就可以理解需要进行多少级别的解析,例如:它是否已经使用CRTP工作,是否由于没有建模命名空间查找规则而导致失败,是否需要知道哪些#if/#else分支被跟踪以获得准确的结果...? - Tony Delroy
1
@DarenW:嗯,听起来你最好还是坚持使用已经适合你的东西。 - Tony Delroy
显示剩余6条评论
7个回答

11

我建议使用Clang

它是一个基于C++库设计的编译器,注重易于重用。这意味着您可以仅使用它来解析和生成抽象语法树,而无需处理所有繁琐的运算符重载解析、模板实例化等问题。

Clang提供了一个基于C语言的接口,并通过Python绑定进行扩展。该接口通常非常丰富,但我没有使用过。如果您希望帮助扩展它,欢迎贡献。


我完全不知道CLang已经处于这样的状态了。谢谢你指出来! - Alexandre Araujo Moreira
我已经尝试使用CLang来编译整个项目,但是它在解析方面存在一些晦涩的漏洞,导致构建无法进行得太远。不过,再试一次也是值得的,因为我喜欢有意义的错误信息。对于仅分析源代码而不进行构建,它可能是最好的工具。 - DarenW
就此而言,官方的Clang网站将Clang拼写为小写字母L。 - Thomas Eding
@trinithis:是的,这是个打字错误。我倾向于按 Shift 键按得有点太久了 :x 谢谢你指出来。 - Matthieu M.

6
你可以查看GccXML和OpenC++,以及doxygen。

OpenC++已经有些过时了。 - Ira Baxter
“长了牙齿”是什么意思? - tenfour
@tenfour: long in the tooth === 老 (因为老年人的牙齿更长、更扭曲)。 - Martin York
1
“Long in the tooth” 这个词语与马匹牙齿逐渐退化有关,但本人并非马匹专家。 - DarenW

3

你能运行预处理步骤吗?Doxygen解析大部分C++语法并创建带有所有关系的xml。编译器还会创建调试数据库(通常是来自gcc的dwarf格式和来自MSC的codeview格式)。


我们使用Doxygen,但这是否意味着我必须解析XML才能得到我想要的内容? - DarenW
@DarenW:Python有一个XML库,是吗?因此,所有繁重的解析工作都应该为您完成,您只需要使用对象模型提取所需的详细信息。 - Ben Voigt

1
从你对我们需求的描述来看,Tony提供的GccXML可能是最好的选择。如果这不起作用,你可以尝试使用cscope或ctags生成程序的大纲,然后从输出中找到所需的信息。

Ctags使用-x选项编写类似于我正在尝试创建的信息。但它并不完全正确。也许可以将其调整为我所需的内容。 - DarenW

1
你要求可以从C++中提取信息的工具。
我们的DMS软件重构工具包是一种可配置的编译器技术,用于构建自定义分析器。它具有完整的C++前端,包括预处理器、完整的C++解析和AST构建(包括注释捕获)以及完整的符号表。这些可以用来提取这样的结构信息,并将其导出到您想要处理的任何地方。
编辑:其中一条评论是世界上只有3个完整的C++ 解析器。 我怀疑还有更多;肯定IBM有一个可用的。DMS的C++前端已经在MS Visual Studio和GNU C ++源代码中的大型应用程序中使用过,因此它也可能合格 :-}

0

3
如果你想要一个完整的C++解析器,除非你想以此为职业,否则不建议自己动手构建。相信我。 - Ira Baxter
1
这不是 OP 所问的。从 GCC 中获取 AST 可能是最好的选择,但是 OP 似乎并不想要完全解析。 - Foo Bah
如果他不使用完整解析器,他的答案将不准确。如果他不关心自己的答案是否准确,也许一些黑客技巧可以奏效。但那通常最终会变得相当令人不满意。 - Ira Baxter

0

如果你能够使用 Windows 平台应用程序运行此分析,那么可以省下很多时间和麻烦,并花费 $200 在 Sparx Systems 的 Enterprise Architect 上(我与该公司无关,只是一个满意的客户)。(注意:这不应与 Microsoft 自己的“Visual Studio”捆绑包中的“Enterprise Architect”混淆。)

EA 可以反向工程多种语言,包括 C++、C、Java 和 Python,生成一些非常好的 UML 类图。(EA 有多个不同的包,桌面版最便宜,但你必须购买第二便宜的专业版才能包括代码工程功能。)我还喜欢生成的类图和顺序图之间的集成,在其中您可以在对象生命线之间拖动一条线,并且基于目标对象的类定义向您呈现一系列定义方法的菜单。在我以前的咨询业务中,我们经常使用这个工具制定系统架构方案,然后将其作为我们项目投标的一部分(只需将图表复制/粘贴到 Word 文档中)。你花费的 $200 不会需要很长时间就可以赚回来。


在这里,花钱并且只能在Windows上运行的东西是不会被接受的,因为我们都是基于Linux的物理学家。你主要用它来开发新系统吗?它是否适合用于理解现有的大型代码库? - DarenW
3
有趣的是,我们认为分几周写部分解决方案比花200美元更好 - 通常这被视为无头脑老板的想法。是的,我用它来获取现有代码库的大局观,你只需要将其指向包含代码的目录,选择语言和文件扩展名,然后点击“Go”。当然,它可以生成一些相当复杂的图表,但它会根据您的目录和/或包结构拆分图表,并且您可以在事后简化图表。 - PaulMcG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接