解析C源文件

时间:2012-07-20 18:50:22

标签: java c regex parsing

如果我有一个C源文件,我想在一个函数中找到一个特定的局部变量并使其成为全局 - 所以另一个工具能够处理C文件(我没写的工具)会是什么最简单的方法吗?我正在考虑使用正则表达式,但即使这样也有它自己的问题。这有点像用Java编写一个迷你C解析器。很多工作:S

是否有任何图书馆可以帮助您轻松实现这一目标?

例如,假设我想将变量“i”变为全局变量。用户将指定函数名称和变量名称(但不是变量的类型 - 即“int”)。

我可以使用正则表达式找到函数 - 当然。但是从那里我真的不知道最好的方法是什么?... CDT插件会有帮助吗?

示例:

 /* 
  * add.c
  * a simple C program
  *
  */

#include <stdio.h>
#define LAST 10

int main()
{
    int i = 0;
    int sum = 0;

    for ( i = 1; i <= LAST; i++ ) {
      sum += i;
    } /*-for-*/
    printf("sum = %d\n", sum);

    return 0;
}

转换为:

 /* 
  * add.c
  * a simple C program
  *
  */

#include <stdio.h>
#define LAST 10

int i = 0;

int main()
{

    int sum = 0;

    for ( i = 1; i <= LAST; i++ ) {
      sum += i;
    } /*-for-*/
    printf("sum = %d\n", sum);

    return 0;
}

3 个答案:

答案 0 :(得分:1)

即使你能够想出一种方法来进行这样的转换,我认为这不是一个好主意。由于你在建筑和破坏中移动,程序将不会保持不变。此外,并非所有类型都是默认构造或可复制的,因此通常无法进行转换。

您是否只对几种简单类型感兴趣?然后将其作为解决方案的一部分。是否生成了原始代码?另外,您如何信任仅通过名称识别本地对象?同名也可用于不同类型的对象。

答案 1 :(得分:1)

如果你只做了一些简单的例子,你可以用Perl或一些java正则表达式来解决这个问题。它无法在复杂程序上可靠地工作,因为您需要一个真正的解析器。

我们可以非常可靠地使用DMS Software Reengineering Toolkit及其C Front End

DMS提供通用程序分析和转换功能,通过编程语言描述进行参数化。 DMS的C Front向DMS解释了C的精确语法(对于C的各种方言,包括GCC和MS);它实际上提供了一个完整的解析器,生成抽象语法树(以及反向:来自AST的C代码生成器)这允许DMS准确读取C源文件,包括预处理。

使用AST格式的解析代码,您可以构建DMS函数和/或编写模式以查找函数定义,特别是您的目标变量。然后可以使用DMS代码或可替换的源到源转换来将变量提升出函数,和/或插入代码以跟踪该变量的状态变化,以便可以看到它。

因此,使用DMS和一些自定义代码,您可以实现所需的效果。您提供的示例可能与DMS相当简单,但学习曲线将会很多; DMS很复杂,因为它处理的语言很复杂,你必须学习如何使用它。所以,对于新手来说,这不是一个下午的练习。

注意:您需要对预处理程序执行此操作(否则您通常无法可靠地解析它们)。所以,这应该是你在编译之前做的事情,不应该成为最终代码的一部分。

如果要进行永久性代码更改,则需要解析未处理的代码;这对heckuva来说更难了。 DMS的C前端可以在预处理器指令“结构化”的范围内执行此操作;其中约95%是。所以现在你遇到了一个新问题:要么修复非结构化的(一次性手动更改),要么拒绝无法用“运气不好”解析的文件。

您可以使用GCC代替DMS;毕竟它有一个经过良好测试的C解析器。但是,它无法帮助您生成修改后的C代码。另一个替代方案是Clang,它作为一个相当不错的选择而快速上升。我认为它会解析C ++;不太确定C或特别是最终用户可能使用的C方言(你没说)。它有像DMS这样的AST,以及一种为可能有效的代码生成“补丁”的方案。

答案 2 :(得分:1)

我要求的第一件事是完全确定何时需要这个以及为什么,以及如何在不对程序语义产生负面影响的情况下确定何时安全。这是一个非常糟糕的主意。很明显,那些给你作业的人不知道实现复杂性,这是巨大的,还是不利的语义效应。我猜他们因此无法提出足够的规范,这最终会让你失望。

我也会引起他们的注意,特别是艾拉巴克斯特的评论。我曾经以构建编译器为生。在论坛上学习或询问不是一项任务。