我需要在Linux内核中做一些源代码处理。我试着用clang来达到这个目的,但有一个问题。Clang对源代码进行预处理,即宏和包含扩展。这导致clang有时会在Linux内核方面产生中断的C代码。我无法手动维护所有的更改,因为我希望每个文件都有数千个更改。
我尝试过ANTLR,但是可用的公共语法是不完整的,不适合Linux内核这样的项目。
所以我的问题如下。是否有任何方法可以对C代码执行源到源的操作,而无需对其进行预处理?
因此,假设下面的代码。
#define AAA 1
void f1(int a){
if(a == AAA)
printf("hello");
}
在应用了源到源的操作之后,我想得到以下内容
#define AAA 1
void f1(int a){
if(functionCall(a == AAA))
printf("hello");
}
但是,例如,Clang生成的代码不符合我的要求,即扩展了宏AAA
#define AAA 1
void f1(int a){
if(functionCall(a == 1))
printf("hello");
}
希望我说的够清楚了。
编辑
上面的代码只是一个例子。我想要做的源到源操作不受if()
语句替换的限制,还可以在表达式前面插入一元运算符,将算术表达式替换为正或负值等。
溶液
我为自己找到了一个解决办法。我使用gcc来生成预处理的源代码,然后应用Clang。那么,我对宏观扩张没有任何问题,并且包括在内,因为这是gcc做的。谢谢你的回答!
发布于 2011-08-15 11:38:31
您可以考虑http://coccinelle.lip6.fr/:它提供了一个很好的语义修补框架。
发布于 2011-08-15 00:35:50
一个想法是替换所有发生在
if(a == AAA)
使用
if(functionCall(a == AAA))
您可以很容易地使用sed工具来完成这个任务。
如果要替换的模式集合有限,则可以编写sed脚本来执行替换。
这能解决你的问题吗?
发布于 2011-08-15 11:32:00
在将转换应用于C(和C++)代码时,处理预处理器是最困难的问题之一。
我们的DMS软件重组工具包和它的C前端相对接近于这样做。DMS可以解析C源代码,保留大多数预处理条件,宏定义和使用。
它允许在“结构良好”的地方执行预处理操作。例如:在可能发生声明或语句的地方允许定义,宏调用和条件替换语言中的许多非终端(例如函数头、表达式、语句、声明)和人们通常放置它们的许多非结构化位置(例如,#if fooif (.) {#endif)。它解析源代码和预处理指令,就好像它们是一种语言的一部分(它们是,称为"C"),并构建相应的as,这些as可以被转换,并将正确地与捕获的预处理器指令重新生成。这个能力级别完美地处理了OP的示例。
有些指令的位置很差(在语法意义上,例如,跨语言的多个片段,以及“您一定在开玩笑”的可理解性)。这些DMS通过扩展它们来处理,并得到高级工程师的一些指导(“总是扩展这个宏”)。一种不太令人满意的方法是将非结构化的预处理条件/宏调用转换为结构化的条件;这有点痛苦,但比人们可能预期的要好得多,因为坏的情况发生的频率要比好的低得多。
要做得更好,需要有考虑到预处理条件的符号表和流分析,并捕获所有预处理条件。我们已经在DMS中做了一些实验工作,以捕获符号表中的条件声明(似乎工作得很好),而且我们刚刚开始为后者设计一个方案。
做绿色可不容易。
https://stackoverflow.com/questions/7060697
复制相似问题