C代码中的AST

25

我想在C源代码上执行一些转换。我需要一个在Linux上的工具,从源代码中生成完整的AST,以便我可以在该AST上应用我的变换,然后将其转换回C源代码。我尝试使用ELSA,但它无法编译。(我正在使用Ubuntu 8.4)。有人能推荐一个更好的工具或应用程序吗?


我相信目前来看,OpenC++是您能找到的最接近的选择。 - rektide
11个回答

19

我建议使用clang。它具有相当完整的C实现,支持大多数gcc扩展,并且代码非常易于理解。虽然他们的C++实现不完整,但如果你只关心从C代码生成AST,那么这应该是可以的。根据你想要做什么,你可以将clang作为库直接使用AST进行操作,或者让clang将其导出到控制台。


1
当然可以。这就是clang-cc重写功能的工作原理。举个具体的例子,可以查看http://llvm.org/svn/llvm-project/cfe/trunk/lib/Frontend/RewriteBlocks.cpp,这就是执行`clang-cc -rewrite-blocks`时发生的事情。 - Louis Gerbarg

16

请查看pycparser - 一个用于生成C语言纯Python AST的工具。


3
仅支持C99。对许多人来说可能足够了,但对我来说不够用。 - Engineer

5
我知道两个与您有用的项目: 它们都解析标准的C源代码以允许进一步的分析和转换。我没有使用过它们,所以您需要自己检查它们是否符合您的需求。
当然,使用GCC的建议也是有效的。虽然我知道在这方面gcc上没有太多文档。

据我所知,CIL不会重新生成源代码。 - Ira Baxter
据我所了解,CIL要求您使用OCaml编写AST分析;计划支持C语言。 - Engineer

4
要获得AST XML输出,您可以尝试使用MarpaX::Languages::C::AST中的cscan。输出将如下所示: xml <cscan> <typedef_hash> <typedef id="GLenum" before="unsigned int" after="" file="/usr/include/GL/gl.h"/> ...

3
我们的DMS软件重构工具包已经被用于大型C系统,解析、分析、转换和再生C代码。它可以在Windows上运行,并且可以在Linux下通过Wine运行,但它确实可以处理Linux风格(GCC)的C代码。
我无法强调足够的是能够循环处理C源代码的能力:解析、构建树形结构、转换、再生可编译的C代码,并保留注释和原始程序员的缩进,这点在其他答案中提到的系统中很少能够做到如此稳健。
DMS专门设计用于进行程序转换(与其他答案中提到的系统不同),这也是一个巨大的优势。DMS提供树形模式匹配和重写;它还增加了完整的控制和数据流分析,以扩展您想要匹配的条件。一个旨在成为编译器的工具就是那样的,你将很难说服它不成为编译器,而是像OP请求的那样成为一个转换引擎。
请参阅 https://dev59.com/yEvSa4cB1Zd3GeqPfpQH#2173477,了解 DMS 生成的示例 AST。


2

www.antlr.org


尽管默认的ANTLR发行版不包含C解析器,但是有许多这样的解析器在网络上流传着,只需谷歌一下即可。祝好,Sebastiaan - Sebastiaan M
2
有基于ANTLR的C解析器。我不知道它们中是否有任何一个可以从(修改后的)AST重新生成源代码。 - Ira Baxter

1

我在源代码转换方面做了一些小工作,发现CIL非常适合这项任务。CIL具有专门设计用于静态源代码分析和转换的框架的优势。它还可以处理带有任何数量的丑陋GCC特定扩展的代码(例如,它已被用于处理Linux内核)。不幸的是,它是用OCAML编写的,使用它构建的分析/转换也必须用OCAML编写,如果您从未使用过OCAML可能会有问题。

或者,clang据说具有相对容易可操作的代码库,当然也可以用于生成C AST。


是的,CIL将重新生成可编译的C代码(例如,注释会发生什么?),但不会生成原始程序员可以识别的源代码。这使得CIL对于推理和代码优化非常有用,但不适用于转换程序员的代码。 - Ira Baxter

0
"我尝试过ELSA,但无法编译(我使用的是Ubuntu 8.4)。" Elkhound和Elsa源代码,版本为2005.08.22b,来自scottmcpeak.com/elkhound/已过时(旧的C++样式.h标头文件)。 Elsa正在运行并且是Oink的一部分:http://www.cubewano.org/oink/#Gettingthecode。我刚刚在Ubuntu 9.10下使其工作。"

Elsa 公开承认他们的主页无法处理所有无效的源代码。 - Engineer
1
Elsa是一个解析器生成器,因此转换代码(该过程的输出部分)将是一个挑战。 - Engineer

0

问题在于需要一个相当完整的 C 词法语法,这并不容易,因为存在 C 预处理器、类型规则等问题。 - Remo.D
是的,我知道,但是lex和yacc是非常强大的工具,所以我稍微研究了一下它们,因此我认为这会对某些人有所帮助。因为C语言有点原始,当然这不是一项容易的任务,我完全同意你的看法。 - milot
需要你深入编写MELT扩展。 - Engineer

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