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

时间:2009-02-09 00:48:14

标签: c++ c parsing yacc lex

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

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

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

  • CScope - 老式C分析仪。但是,似乎没有做完整的解析。被描述为寻找C函数的美化'grep'。
  • GCC - 每个人最喜欢的开源编译器。非常复杂,但似乎做到了这一切。有一个用于创建名为GEM的GCC扩展的相关项目,但自GCC 4.1(2006)以来尚未更新。
  • PUMA - PUre MAnipulator。 (来自页面:“这个项目的意图是 提供用于分析和操作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 ++解析树的解决方案。

14 个答案:

答案 0 :(得分:35)

解析C ++非常困难,因为语法是不可判定的。引用Yossi Kreinin

  

非常复杂的语法

     

“Outstandingly”应按字面解释,因为所有流行语言都有context-free(或“几乎”无上下文)语法,而C ++有undecidable语法。如果您喜欢编译器和解析器,您可能知道这意味着什么。如果你没有进入这种事情,有一个simple example显示解析C ++的问题:AA BB(CC);是对象定义还是函数声明?事实证明,答案在很大程度上取决于之前的语句 - “上下文”。这表明(在直观上)C ++语法非常依赖于上下文。

答案 1 :(得分:21)

您可以查看使用llvm进行解析的clang

现在完全支持C ++ link

答案 2 :(得分:17)

ANTLR解析器生成器有一个grammar用于C / C ++以及预处理器。我从来没有使用过它,所以我不能说它对C ++的解析会有多完整。 ANTLR本身在几次解析更简单的语言时对我来说是一个很有用的工具。

答案 3 :(得分:16)

根据您的问题GCCXML可能是您的答案。 基本上它使用GCC解析源代码,然后为您提供易于理解的解析树XML。 使用GCCXML,您可以一劳永逸地完成任务。

答案 4 :(得分:13)

pycparser是用Python编写的C(C99)的完整解析器。它具有完全可配置的AST后端,因此它可以用作您可能需要的任何语言处理的基础。

但是,

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


更新(2012):此时答案毫无疑问是Clang - 它是模块化的,支持完整的C ++(具有许多C ++ - 11功能)并且具有一个相对友好的代码库。它还有一个用于绑定高级语言的C API(即for Python)。

答案 5 :(得分:8)

了解doxygen的工作原理,完整的源代码是否可用,并且它是基于弹性的。

误导性候选者是GOLD,它是一个基于Windows的免费解析器工具包,专门用于创建翻译器。他们的支持的语言列表是指可以实现解析器的语言,而不是支持的解析语法列表。

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

答案 6 :(得分:7)

Parsing C++ is a very complex challenge

有Boost / Spirit框架,几年前他们做过play with the idea of implementing a C++ parser,但它是far from complete

完全正确地解析ISO C ++远非微不足道,实际上还有很多相关的工作。但是,如果不重写完整的编译器前端,了解所有C ++ 预处理器,那么这是一项本身非常复杂的工作,并不容易实现。一个名为“wave”的预处理器实现可以从Spirit人员处获得。

那就是说,你可能想看看pork/oink(基于elsa),这是一个专门用于源代码转换目的的C ++解析器工具包,它正被Mozilla项目使用要做大规模的静态源代码分析和自动代码重写,最有趣的部分是它不仅支持大部分C ++,还支持预处理器本身!

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

就个人而言,我会查看在Mozilla上使用的基于elsa的pork / oink套件,除此之外,FSF现已批准使用运行时库许可证在gcc plugins上进行工作,因此我假设一旦人们可以使用二进制插件轻松利用基于gcc的C ++解析器进行此类目的,事情将会迅速发生变化。

所以,简而言之:如果你有钱:EDG,如果你需要免费的东西/开源现在:else / oink是相当有前途的,如果你有时间,你可能想要将gcc用于您的项目。

仅适用于C代码的另一个选项是cscout

答案 7 :(得分:6)

C ++的语法有点臭毛茸茸。有a good thread at Lambda about it,,但要点是C ++语法可能需要任意多的预测。

对于我想象你可能会做的事情,我会考虑攻击Gnu CC或Splint。特别是Gnu CC确实将语言生成部分彻底分离出来,所以你可能最好建立一个新的g ++后端。

答案 8 :(得分:4)

实际上,PUMA和AspectC ++仍然在积极维护和更新。我正在研究使用AspectC ++,并且想知道自己缺少更新。我通过电子邮件发送了作者,他说AspectC ++和PUMA都在开发中。您可以通过SVN https://svn.aspectc.org/repos/获取源代码,也可以在http://akut.aspectc.org获得常规二进制构建。与目前许多优秀的c ++项目一样,作者没有时间跟上网页维护。如果你有一份全职工作和生活,那就没有意义。

答案 9 :(得分:3)

Elsa击败了我知道用于C ++解析的其他所有内容,即使它不是100%兼容的。我是一个粉丝。有一个打印出C ++的模块,因此这可能是您玩具项目的一个很好的起点。

答案 10 :(得分:2)

tiny-CSmall C

更易于理解的内容

答案 11 :(得分:2)

查看我们的C++ Front End 对于功能齐全的C ++解析器:构建AST,符号表,确实命名 和类型分辨率。您甚至可以解析并保留预处理器 指令。 C ++前端构建在DMS Software Reengineering Toolkit之上,允许您使用该信息执行任意操作 源代码使用源到源转换进行更改。

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

话虽如此,我没有看到你想象中的任务有多大意义;我不 在尝试替换C ++时看到了很多价值,你会发现构建 一个完整的翻译工作量巨大,特别是如果你的 目标是一种“玩具”语言。并且可能没有什么意义 使用强大的解析器解析C ++,如果它的唯一目的是生成 一个易于解析的C ++同构版本(等待,我们假设 一个强大的C ++已经!)。

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

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

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

答案 12 :(得分:1)

前段时间我试图编写一个工具,自动为c文件生成单元测试。

对于预处理,我将文件放在GCC中。输出很难看,但您可以轻松地从预处理文件中跟踪原始代码中的位置。但是根据您的需求,您可能还需要其他东西。

我使用Metre作为C解析器的基础。它是开源的,使用lex和yacc。这使得在不完全理解lex& amp;的情况下,很容易在短时间内启动和运行。 YACC。

我也写了一个C app,因为lex& yacc解决方案无法帮助我跨函数跟踪功能,并在一次通过中解析整个函数的结构。它在短时间内变得无法维护并被遗弃。

答案 13 :(得分:1)

如何使用像GNU CFlow这样的工具来分析代码并生成调用图表,这就是opengroup(手册页)对cflow的看法。 GNU版本的cflow附带源代码,开源代码也是......

希望这有帮助, 最好的祝福, 汤姆。