有什么好的工具可以快速开始解析和分析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++解析树的解决方案.
解析C++非常困难,因为语法是不可判定的.引用Yossi Kreinin:
非常复杂的语法
"Outstandingly"应该从字面上解释,因为所有流行语言都有无上下文(或"几乎"无上下文)的语法,而C++有不可判定的语法.如果您喜欢编译器和解析器,您可能知道这意味着什么.如果你不是这样的话,有一个简单的例子说明解析C++的问题:是
AA BB(CC);
对象定义还是函数声明?事实证明,答案在很大程度上取决于声明之前的代码- "上下文".这表明(在直观上)C++语法非常依赖于上下文.
你可以看看使用llvm进行解析的clang.
现在完全支持C++ 链接
所述ANTLR解析器生成具有语法为C/C++以及预处理器.我从来没有使用过它,所以我不能说它对C++的解析会有多完整.ANTLR本身对我来说是一个很有用的工具,用于解析更简单的语言.
根据您的问题,GCCXML可能就是您的答案.基本上它使用GCC解析源代码,然后为您提供易于理解的解析树XML.使用GCCXML,您可以一劳永逸地完成任务.
pycparser是用Python编写的C(C99)的完整解析器.它具有完全可配置的AST后端,因此它可以用作您可能需要的任何语言处理的基础.
但是,不支持C++.当然,它比C 要难得多.
更新(2012):此时答案毫无疑问是Clang - 它是模块化的,支持完整的C++(具有许多C++ - 11功能)并且具有相对友好的代码库.它还有一个用于绑定高级语言的C API(即Python).
看看doxygen如何工作,完整的源代码是可用的,它是基于flex的.
一个误导性的候选者是GOLD,这是一个免费的基于Windows的解析器工具包,明确用于创建翻译器.它们支持的语言列表是指可以实现解析器的语言,而不是支持的解析语法列表.
它们只有C和C#的语法,没有C++.
解析C++是一项非常复杂的挑战.
有Boost/Spirit框架,几年前他们确实采用了实现C++解析器的想法,但它远未完成.
完全正确地解析ISO C++远非微不足道,实际上还有很多相关的工作.但是,如果不重写完整的编译器前端来理解所有C++ 和预处理器,那么这是一项本身就很复杂的工作,并不容易实现.一个名为"wave"的预处理器实现可以从Spirit人员那里获得.
也就是说,您可能想看看pork/oink(基于elsa),这是一个专门用于源代码转换目的的C++解析器工具包,它正被Mozilla项目用于大规模静态源代码分析和自动代码重写,最有趣的部分是它不仅支持大部分C++,还支持预处理器本身!
另一方面,确实有一种可用的专有解决方案:EDG前端,可用于几乎所有与C++相关的工作.
就个人而言,我会查看在Mozilla上使用的基于elsa的pork/oink套件,除此之外,FSF现在已经批准了使用运行时库许可证的gcc插件工作,因此我认为事情会发生变化一旦人们可以使用二进制插件轻松地利用基于gcc的C++解析器进行此类目的.
所以,简而言之:如果你有钱:EDG,如果你现在需要免费/开源的东西:else/oink相当有前途,如果你有时间,你可能想要为你的项目使用gcc.
C代码的另一个选择是cscout.
C++的语法有点臭毛茸茸.Lambda关于它有一个很好的线索,但要点是C++语法可能需要任意多的前瞻性.
对于我想象你可能会做的事情,我会考虑攻击Gnu CC或Splint.特别是Gnu CC确实将语言生成部分彻底分离出来,所以你可能最好建立一个新的g ++后端.