用于创buildC / C ++分析器/分析器的好工具

有什么好的工具可以快速开始parsing和分析C / C ++代码?

特别是,我正在寻找处理C / C ++预处理器和语言的开源工具。 优选地,这些工具将对语法使用lex / yacc(或flex / bison),而不是太复杂。 他们应该处理最新的ANSI C / C ++定义。

这是我到目前为止发现的,但没有详细看过他们(想法?):

  • CScope – 老式C分析仪。 虽然似乎没有做一个完整的parsing。 被形容为一个寻找C函数的荣耀的“grep”。
  • GCC – 大家最喜欢的开源编译器。 非常复杂,但似乎这样做。 有一个创buildGCC扩展名为GEM的相关项目,但自从GCC 4.1(2006)以来并没有更新。
  • PUMA – PUre MAnipulator。 (来自页面:“这个项目的意图是提供一个用于分析和操作C / C ++源的类库,为此,PUMA提供了用于扫描,parsing和当然操作C / C ++源的类。 。 这看起来很有希望,但自2001年以来一直没有更新。显然PUMA已经被纳入了AspectC ++ ,但是这个项目自2006年以来还没有更新。
  • 各种C / C ++原始语法。 你可以得到c-c ++ – grammars-1.2.tar.gz ,但是自1997年以来,这个问题一直没有得到维护。一些Googlesearch把其他基本的lex / yacc语法作为起点。
  • 其他人?

我希望把它作为将C / C ++源代码翻译成新的玩具语言的起点。

谢谢! -Matt

(已添加2/9):只是澄清:除了C / C ++代码本身之外,我想从预处理程序中提取语义信息。 我不希望“#define foo 42”消失到整数“42”中,但仍然附加到名称“foo”。 不幸的是,这不包括几个运行预处理器的解决scheme,只能提供C / C ++parsing树)

parsingC ++是非常困难的,因为语法是不可判定的。 引用Yossi Kreinin的话 :

非常复杂的语法

“出乎意料”应该从字面上解释,因为所有stream行的语言都有上下文无关 (或“接近”上下文无关)的语法,而C ++有不可判断的语法。 如果你喜欢编译器和parsing器,你可能知道这意味着什么。 如果你不是这样的事情,有一个简单的例子显示parsingC ++的问题:是AA BB(CC); 一个对象定义还是一个函数声明? 事实certificate,答案在很大程度上取决于语句之前的代码 – “上下文”。 这表明(在直观的层面上)C ++语法是相当敏感的。

你可以看看使用llvm进行parsing的clang 。

现在完全支持C ++ 链接

ANTLRparsing器生成器具有用于C / C ++的语法以及预处理器。 我从来没有用过它,所以我不能说C ++的parsing将会是多么完整。 对于parsing更简单的语言,ANTLR本身对我来说是一个有用的工具。

根据你的问题GCCXML可能是你的答案。 基本上它使用GCCparsing源代码,然后给你简单易懂的parsing树的XML。 有了GCCXML,你就完成了一次。

pycparser是用Python编写的C(C99)的完整parsing器。 它有一个完全可configuration的AST后端,所以它被用作任何你可能需要的语言处理的基础。

不过,不支持C ++。 当然,这比C更难


更新(2012) :在这个时候,毫无疑问,答案将是Clang – 它是模块化的,支持完整的C ++(具有许多C ++ – 11特性),并且具有相对友好的代码库。 它还有一个C API用于绑定到高级语言(例如Python )。

看看Doxygen如何工作,完整的源代码是可用的,它是基于Flex的。

误导性的候选人是GOLD ,这是一个免费的基于Windows的parsing器工具包,用于创build翻译器。 它们的支持语言列表是指可以实现parsing器的语言,而不是支持的parsing语法列表。

他们只有C和C#的语法,没有C ++。

C ++的语法有点臭名昭着。 Lambda对此有一个很好的线索,但要点是C ++语法可能需要非常多的前瞻。

对于我认为你可能会做的事情,我会考虑对Gnu CC或者Splint进行黑客攻击。 Gnu CC特别将语言生成部分分开,所以您可能最好build立一个新的g ++后端。

parsingC ++是一个非常复杂的挑战 。

有Boost / Spirit框架,几年前,他们确实发挥了实现一个C ++parsing器的想法 ,但还远远没有完成 。

完全正确的parsingISO C ++并不是一件容易的事情,事实上还有许多相关的工作。 但是,如果不重新编写一个完整的编译器前端,了解所有的C ++ 预处理器,就不是一件容易实现的内在复杂的工作。 一个叫做“波”的预处理器实现可以从Spirit人那里获得。

也就是说,您可能需要查看基于elsa的猪肉/ oink (这是一个专门用于源代码转换目的的C ++parsing器工具包),Mozilla项目正在使用它进行大规模静态源代码分析和自动化代码重写,最有趣的部分是它不仅支持大部分C ++,而且还支持预处理器本身!

另一方面,确实有一个可用的专有解决scheme:EDG前端,可用于几乎所有与C ++有关的工作。

就我个人而言,我会查看Mozilla使用的基于elsa的猪肉/ oink套件,除此之外,FSF现在已经批准使用运行时库许可证对gcc插件进行工作,因此我认为事情将会改变很快,一旦人们可以很容易地利用基于gcc的C ++parsing器来实现这种使用二进制插件的目的。

所以,简而言之,如果你是雄鹿:EDG,如果你现在需要一些免费/开放源代码:else / oink是相当有前途的,如果你有一些时间的话,你可能想要为你的项目使用gcc。

C代码的另一个select是cscout 。

实际上,PUMA和AspectC ++仍然在积极维护和更新。 我正在研究使用AspectC ++,并想知道自己缺less更新。 我给那位说AspectC ++和PUMA都在开发的作者发了电子邮件。 您可以通过SVN https://svn.aspectc.org/repos/获得源代码,或者您可以在http://akut.aspectc.org获得常规二进制版本。; 就像现在很多优秀的c ++项目一样,作者没有时间跟上网页的维护。 如果你有一个全职工作和一个生活是有意义的。

Elsa击败了我熟悉的C ++parsing手段,尽pipe它不是100%兼容的。 我是粉丝。 有一个打印出C ++的模块,所以这可能是你玩具项目的一个很好的起点。

如何更容易理解,如微小C或小C

请参阅我们的C ++前端,了解全function的C ++parsing器:构buildAST,符号表,名称和typesparsing。 你甚至可以parsing和保留预处理指令。 C ++前端build立在我们的DMS Software Reengineering Toolkit之上,它允许您使用这些信息来执行使用源到源转换的任意源代码更改。

DMS是实现这种翻译器的理想引擎。

话虽如此,我并没有在你想象中的任务中看到太多的重点。 在replaceC ++方面,我看不出什么价值,而且你会发现构build一个完整的翻译是一项巨大的工作,特别是如果你的目标是“玩具”语言的话。 如果C ++的唯一目的是生成一个易于parsing的C ++同构版本(等待,我们假设已经有一个健壮的C ++),那么使用强健的parsing器parsingC ++可能就没什么意义了。

编辑2012年5月:DMS的C ++前端现在可以处理GCC3 / GCC4 / C ++ 11,Microsoft VisualC 2005/2010。 强劲。

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

编辑2015年8月:现在parsing并捕获统一树中的代码和预处理器指令。

后来我试图编写一个工具,它会自动生成c文件的unit testing。

为了preproosessing我把文件通过海湾合作委员会。 输出是丑陋的,但你可以很容易地跟踪预处理文件中原始代码的位置。 但为了您的需要,您可能还需要别的东西。

我使用Meter作为C语言分析器的基础。 它是开源的,使用lex和yacc。 这使得在不了解lex&yacc的情况下很容易在短时间内启动并运行。

我还写了一个C应用程序,因为lex&yacc解决scheme无法帮助我追踪跨function的function,并一次性parsing整个function的结构。 在短时间内变得不可维护,被遗弃。

怎么样使用像GNU的CFlow这样的工具,可以分析代码并生成调用图的图表,下面是opengroup (手册页)对cflow的说明。 cflow的GNU版本带有源代码,开放源码也是…

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