【问题标题】:AST from C code [closed]来自 C 代码的 AST [关闭]
【发布时间】:2016-05-05 14:22:22
【问题描述】:

我想对 C 源代码进行一些转换。 我需要一个在 linux 上从源代码生成完整 AST 的工具,以便我可以在此 AST 上应用我的转换,然后将其转换回 C 源代码。我试过ELSA,但它没有被编译。 (我使用的是 Ubuntu 8.4)。谁能推荐一个更好的工具/应用程序?

【问题讨论】:

  • 我相信 OpenC++ 与您现在所获得的一样接近。

标签: c abstract-syntax-tree


【解决方案1】:

我会推荐clang。它有一个相当完整的 C 实现,带有大多数 gcc 扩展,并且代码非常易于理解。他们的 C++ 实现是不完整的,但如果您只关心从 C 代码生成 AST 应该没问题。根据您的需要,您可以使用 clang 作为库并直接使用 AST,或者让 clang 将它们转储到控制台。

【讨论】:

【解决方案2】:

请参阅 pycparser - 用于 C 的纯 Python AST 生成器。

【讨论】:

  • 仅支持 C99。对许多人来说可能就足够了。不适合我。
【解决方案3】:

我知道有两个项目对您有用:

它们都解析标准 C 源代码以允许进一步分析和转换。我没有使用它们,因此您必须自己检查它们是否符合您的需求。

当然,使用 GCC 的建议也是有效的。不过,我知道关于 gcc 这方面的文档并不多。

【讨论】:

  • CIL 不会重新生成源代码,AFAIK。
  • 据我所知,CIL 要求您在 OCaml 中编写 AST 分析;计划支持 C 语言。
【解决方案4】:

要获得 AST XML 输出,您可以尝试使用来自 MarpaX::Languages::C::ASTcscan。输出将如下所示:

xml <cscan> <typedef_hash> <typedef id="GLenum" before="unsigned int" after="" file="/usr/include/GL/gl.h"/> ...

【讨论】:

    【解决方案5】:

    www.antlr.org

    【讨论】:

    • 虽然默认的 ANTLR 发行版不包含 C 解析器,但其中有很多浮动,只需 google 即可。问候,塞巴斯蒂安
    • 有基于 ANTLR 的 C 解析器。我不知道他们是否可以从(修改的)AST 重新生成源代码。
    【解决方案6】:
    【解决方案7】:

    我们的DMS Software Reengineering Toolkit 已用于大型 C 系统,解析、分析、转换和重新生成 C 代码。在 Windows 上运行,并将在 Wine 下的 Linux 上运行,但它确实处理 Linux 风格 (GCC) C 代码。

    我不能再强调往返 C 源代码的能力:解析、构建树、转换、重新生成可编译的 C 代码与 cmets 和漂亮打印或与原始程序员的缩进。这里很少有其他答案建议系统可以稳健地做到这一点。

    DMS 旨在执行程序转换(与此处的答案中建议的其他系统相反)这一事实也是一个很大的优势。 DMS 提供树模式匹配和重写;它通过完全控制和数据流分析增强了这一点,用于扩展您想要匹配的条件。打算成为编译器的工具就是这样,您将很难说服它不是编译器,而是按照 OP 的要求成为转换引擎。

    参见https://stackoverflow.com/a/2173477/120163,例如 DMS 生成的 AST。

    【讨论】:

      【解决方案8】:

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

      另外,clang 应该有一个相对容易破解的代码库,它当然可以用来生成 C AST。

      【讨论】:

      • 是的,CIL 将重新生成可编译的 C 代码(例如,cmets 会发生什么情况?)只是原始程序员无法识别源代码。这使得 CIL 可用于推理和代码优化,但不适用于转换程序员的代码。
      【解决方案9】:

      您可以尝试在 Linux 上使用 Lexx 和 Yacc 生成 AST(抽象语法树):

      lex and yacc

      from lex and yacc to ast

      【讨论】:

      • 问题是要有一个相当完整的 C lex 语法,由于 C 预处理器、键入规则等原因,这不是一件容易的事
      • 是的,我知道,但是 lex 和 yacc 是非常强大的工具,所以我对它们进行了一些处理,所以我认为它会对解决这个问题的人有所帮助。因为 C 有点原始,当然这不是一件容易的事,我完全同意你的看法。
      • 要求你认真写MELT扩展。
      【解决方案10】:

      “我尝试了 ELSA,但没有得到 编译。 (我使用的是 Ubuntu 8.4)”

      来自 scottmcpeak.com/elkhound/ 的 Elkhound 和 Elsa 源代码版本 2005.08.22b 已过时(旧的 C++ 样式 .h 头文件)。

      Elsa 正在工作并且是 Oink 的一部分:http://www.cubewano.org/oink/#Gettingthecode 我刚刚让它在 Ubuntu 9.10 下运行。

      【讨论】:

      • Elsa 公开承认没有处理其主页上的所有无效源代码。
      • Elsa 是一个解析器生成器,因此转换代码(该过程的输出部分)将是一个挑战。
      【解决方案11】:

      使用 gcc 并为其编写自定义后端怎么样?我从来没有做过,也没有研究过 gcc 源代码,所以我不知道这有多难。

      【讨论】:

      • 在应用转换后如何让它重新生成源代码?
      猜你喜欢
      • 1970-01-01
      • 2013-02-17
      • 2010-11-21
      • 2015-09-14
      • 1970-01-01
      • 2013-12-13
      • 2013-06-18
      • 2013-11-04
      • 1970-01-01
      相关资源
      最近更新 更多