创建C/C++解析器/分析器的好工具

53
有哪些用于快速开始解析和分析C/C++代码的好工具?
特别是,我在寻找处理C/C++预处理器和语言的开源工具。最好,这些工具应该使用lex/yacc(或flex/bison)作为语法,并且不要太复杂。它们应该处理最新的ANSI C/C++定义。
到目前为止,我找到了以下工具,但还没有详细了解它们(有什么想法?):
  • CScope - 传统的C分析器。看起来似乎并没有进行完整的解析。被描述为寻找C函数的“增强版grep”。
  • GCC - 每个人都喜欢的开源编译器。非常复杂,但似乎做了所有的事情。有一个相关的项目用于创建GCC扩展,称为GEM,但自GCC 4.1(2006年)以来就没有更新了。
  • PUMA - 纯粹的操作者。 (来自页面:“此项目的目的是为C/C++源代码分析和操作提供类库。为此,PUMA提供了用于扫描、解析和当然操作C/C++源代码的类。”)。这看起来很有前途,但自2001年以来就没有更新。显然,PUMA已经并入AspectC++,但即使是这个项目也自2006年以来没有更新。
  • 各种 C/C++ 原始语法。你可以获取c-c++-grammars-1.2.tar.gz,但是自 1997 年以来就没有维护过了。通过少量的谷歌搜索可以找到其他基本的 lex/yacc 语法,可以作为起点。
  • 还有其他的吗?

我希望将其用作将 C/C++ 源代码翻译成一种新的玩具语言的起点。

谢谢! -Matt

(添加于 2/9):只是一个澄清:我希望从预处理器中提取语义信息,除了 C/C++ 代码本身。我不想让 "#define foo 42" 消失到整数 "42" 中,而是保持与名称 "foo" 相关联。这使得几个运行预处理器后仅提供 C/C++ 解析树的解决方案被排除在外。


马特,我认为这是一个徒劳的希望;预处理器根据定义在分析之前处理源代码。至少旧的管道编译器在解析之前将预处理后的源代码放入管道中。也许你可以使用cpp嵌入式注释? - Charlie Martin
你可以在源代码上运行自己的处理器。它会输出一个带注释的源代码。你需要修改你的工具所使用的C++语法来读取这些注释。嘿,既然涉及到C++,你就知道这不会很容易 :) - Sean McCauliff
2
被浏览了42,000次?我认为这个应该重新开放。如果你同意,请点击上面的“重新开放”。 - Ira Baxter
我认为这个问题应该重新开放。所有“最佳实践相关的问题”都被标记为离题,但有些可能具有技术维度、客观原因;这不是一个主观的、个人的问题。 - tolga
14个回答

3
"Elsa"是我所知道的最好的C++解析工具,即使它不是100%兼容。我是它的粉丝。有一个打印C++代码的模块,这可能是你的玩具项目的好起点。链接

当我尝试在我的C++文件上运行它时,它停止并显示“未实现”或类似的内容。 - Aftershock
这些工具似乎是基于网站上的日期,最后一次更新是在2005年;作者声称“尝试解析由C++03规范定义的C ++”。它依赖于其他东西来进行预处理。 - Ira Baxter
Ira,今天我毫不犹豫地推荐clang。虽然在2009年它还不够好。 - user52875

3
查看我们的C++前端,它是一个功能齐全的C++解析器:构建AST、符号表,执行名称和类型解析。您甚至可以解析并保留预处理指令。C++前端基于我们的DMS软件重构工具包构建,这使您可以使用该信息来进行任意源代码更改,使用源到源转换。

DMS是实现此类翻译器的理想引擎。

话虽如此,我认为你想象中的任务没有太大意义;我不认为尝试取代C ++有多大价值,并且如果您的目标是“玩具”语言,则会发现构建完整的翻译器需要大量工作。如果其唯一目的是生成易于解析的C++同构版本(等等,我们已经假设了一个强大的C++!),则几乎没有解析C ++使用强大解析器的必要性。

编辑于2012年5月:DMS的C ++前端现在可以处理GCC3 / GCC4 / C ++ 11、Microsoft VisualC 2005/2010。稳定可靠。

编辑于2015年2月:现在可以处理GCC和MS方言中的C ++ 14。

编辑于2015年8月:现在可以以统一树形式解析和捕获代码和预处理指令。

编辑于2020年5月:过去几年一直在处理C++17。正在进行C++20。


5
抱歉,我不能为了推销商业软件而篡改问题或答案。我的职责是提供准确的翻译,并保持中立和客观。 - t0mm13b
1
重复的问题是:“我如何轻松地构建一个复杂的语言处理器?” a)你做不到,b)这个引擎旨在尽可能地使其易于实现(我没有说很容易)。 - Ira Baxter
4
引用原帖内容:“特别是,我正在寻找开源工具”- DMS是否为开源的? - Morten Jensen
DMS不是开源的,这在SO批准的措辞“我们的XXXX”中已经明确表示,即使您不知道这一点。我没有看到任何必要去讨论其他人已经在这里做过的开源工具。它们基本上都无法完成OP所需的任务,因此他必须寻找其他地方,例如商业领域。我们是唯一一个商业(或实际上任何类型的)工具,我知道可以满足他的需求,包括捕获预处理器指令,因此我的回答是相关的。 - Ira Baxter
其次,虽然我的回答指出了OP的唯一真正解决方案之一,但我的回答更关注他的意图和期望结果。他实际上不会构建另一种替代方案,因为a)他没有精力去做这件事,b)因为它根本没有机会取代真正的C ++。[是的,这个回复有点晚了,但Morton的评论让我很困扰。] - Ira Baxter

1

一段时间以前我尝试编写一个工具,用于自动生成C文件的单元测试。

为了预处理,我通过GCC处理文件。输出结果很丑陋,但是你可以轻松追踪到在预处理文件中原始代码的位置。但是根据你的需求,你可能需要其他东西。

我使用Metre作为C解析器的基础。它是开源的,使用lex和yacc。这使得我能够在短时间内快速上手,而不必完全理解lex和yacc。

此外,我还编写了一个C应用程序,因为lex和yacc的解决方案无法帮助我跨函数跟踪功能并一次性解析整个函数的结构。它在短时间内变得难以维护,并被放弃了。


1

使用类似GNU的CFlow这样的工具如何?它可以分析代码并生成调用图表,以下是opengroup(man页面)对cflow的介绍。GNU版本的cflow附带源代码,也是开源的...

希望这有所帮助, 最好的问候, 汤姆。


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