Foo*_*ooF 12 c refactoring automation code-generation program-transformation
我希望有一个命令行工具从C或C++源文件中提取定义或声明(typedef,structure,enumeration,variable或function).另外一种替换现有定义/声明的方法也很方便(在用户提交的脚本转换提取的定义之后).是否有这样的通用工具,或者是这种工具的一些合理的近似值?
脚本性和与用户创建的脚本或程序连接的能力在这里很重要,尽管我在学术上也对GUI程序感到好奇.Unix/Linux阵营的开源解决方案是首选(尽管我对Windows和OS X工具也很好奇).主要的语言兴趣是C和C++,但更通用的解决方案会更好(我认为我们不需要超级准确的解析功能来查找,提取和替换程序源文件中的定义).
示例用例(额外 - 用于好奇心灵):
structs和这些类型的变量(数组)初始化,假设需要通过添加或重新排序字段或以更易读的格式重写变量/数组定义来更改结构定义,而不会引入手工劳动产生的错误.这可以通过提取旧的初始化,然后使用脚本/程序编写新的初始化来替换旧的初始化来实现.替代问题:如果有一个工具来告诉定义的位置(开始和结束行就足够了 - 我们甚至可以假设我们感兴趣的所有定义/声明都在他们自己的行中),那么它只是一个简单的练习手指灵巧地写一个程序
提取定义,运行由命令行选项(或编辑器)指定的程序
stdin(或从临时文件)接收所需的提取定义,stdout(或将它们保存到给定的临时文件)被执行程序取代.
因此,主要的,更具挑战性的问题是找到定义的开始和结束行.
备注标签:更准确的标签比code-generation会code-transformation,但它不存在.
我们的DMS 软件重组工具包正在努力成为您想要的工具。但它正在推动最先进的技术发展,并不是一种涅槃式的工具。做真实的、有趣的工作就足够了。
DMS 提供了解析、分析和转换源代码的通用工具。
它使用显式语法来定义语言(例如C和C++);语法驱动构建抽象语法树(AST)的解析器。各种分析原语提供了 a) 设施 [“属性语法” ATG],用于沿着与 AST 形状很好匹配的树状信息流路径收集信息,b) 构建符号使用到符号定义映射 [“符号表”] ,c)使用 ATG 提取的事实进行控制和数据流分析,d)范围分析,e)本地和全局的点分析。这些原始分析器可用于从 AST 中组合事实,以得出有关 AST 表示的代码的结论(例如,“此语句修改这些变量”)。语言前端将语法和特定于语言的分析器打包在一个可重用的包中。DMS 为多种语言提供了不同深度和成熟度的语言前端。
[编辑 6/27:C 和 C++ 前端支持 C 和 C++ 的特定方言:ANSIC、C99、GCC3/4 C、MS Visual C、ANSI C++98、ANSI C++11、GCC3/4 C++、MS Visual C++ 2005/2008/2010。如果你想准确分析代码,你应该使用“正确”的方言来处理你的代码。]
但“分析”不是重点。分析的目的是推动变革。DMS 提供了额外的支持来程序性地修改 AST,通过以语言表面语法编写的源到源重写规则(均以某些选定的分析结果为条件)来修改 AST,或者对过程集和源到集进行分组-源代码一起重写以进行复合、复杂的重写,可以进行大量代码更改,例如重新架构等。在 AST 转换后,它们可用于在相应的前端重新生成(“prettyprint”)语法正确的代码-最终语言/方言。[通过分段修改一种语言的 AST,直到获得另一种语言的 AST,您可以构建翻译器,但这并不像这句话所暗示的那么容易]。
这一切都在相当程度上发挥了作用,但仍然受到某些语言复杂性的阻碍。对于 C 和 C++,一个著名的复杂问题是预处理器。通过任意编辑程序文本,预处理器条件可以使源代码无法被任何类似于标准解析技术的东西解析。DMS 的 C 和 C++ 前端在一定程度上改善了这一点,并且可以使用结构良好的预处理器指令解析代码,包括一些大多数人不会称之为结构化但经常发生的奇怪情况:
#IF cond
if (abc) {
#ELSE
if (def) {
#ENDIF
Run Code Online (Sandbox Code Playgroud)
我们在通过任意放置预处理器条件来解析代码方面取得了有趣的进展。但是一旦你这样做了,现在所有的分析器突然都必须考虑预处理器条件,而我们突然就处于人们没有真正访问过的编译器的地盘上。
DMS 已用于在大型 C++ 程序中进行重大架构转变,通过大量代码改组从非 CORBA 风格转换为 CORBA 风格,沿着任意控制流路径提取代码,为现有 C 代码生成 SOW 风格的 API,在大型 C 程序中插入检测以检测指针错误等。[它已应用于许多其他语言的其他任务]。
根据我们自己的经验,它仍然很难使用。我们认为,这与民主是除其他所有政府制度之外的所有政府制度中最糟糕的含义是一样的。YMMV。该网站有许多 DMS 衍生工具和讨论。
事实上,它已被用来提取函数(SOW 练习比这更普遍)和插入函数(这是仪器的通用情况)。
GCC-XML 等工具是 DMS 功能的影子。GCC-XML 解析、构建符号表并转储数据声明(而不是代码),但它不能进行任何代码更改。叮当声更好;它将 C 和 C++ 解析为 AST,可以对 LLVM 中间表示进行分析,并且具有某种机制,可以根据所需的树更改向源文本吐出稍后应用的补丁。我不知道 Clang 是否可以进行大规模的代码转换,尤其是那些一次转换的结果再次转换的情况(如何修改延迟文本补丁的树?)。DMS 可以整天执行此操作,并且可以对 C 和 C++ 以外的许多语言执行此操作,并且可以对其所知道的语言的任意混合执行此操作。
在解决带有条件的预处理器问题之前,分析/转换 C 和 C++ 代码并不容易。我们仅凭纯粹的意志力并使用我们可以构建的最强大的工具,就可以在这些语言上成功完成这些任务。(Java不存在这些问题,DMS相应地更擅长分析/转换它)。
冒着严重的傲慢风险,我相信 DMS 是通用分析和转换的最佳工具。作为它的架构师,我将其视为我的长期工作,以使其更加强大地完成这项任务。