C++ 用于解析代码的gcc

C++ 用于解析代码的gcc,c++,c,parsing,gcc,C++,C,Parsing,Gcc,我想知道如何使用GCC作为库来解析我的程序的C/C++/Java/Objective C/Ada代码。 我想绕过预处理,为用户编写的所有函数加上前缀My。 像这样Print()变成MyPrint()我也希望对变量执行此操作。您可以在这里查看: 这是如何使用GCC插件接口解析C++代码的描述。其他语言也应以同样的方式处理 你也可以试试mozilla的猪肉: 当我尝试它(pork)时,我花了大约一个小时来修复编译问题,但是 我可以编写如下脚本: rewrite SyncPrimitiveUpgr

我想知道如何使用GCC作为库来解析我的程序的C/C++/Java/Objective C/Ada代码。 我想绕过预处理,为用户编写的所有函数加上前缀My。 像这样
Print()变成
MyPrint()我也希望对变量执行此操作。

您可以在这里查看:

这是如何使用GCC插件接口解析C++代码的描述。其他语言也应以同样的方式处理

你也可以试试mozilla的猪肉:

当我尝试它(pork)时,我花了大约一个小时来修复编译问题,但是 我可以编写如下脚本:

rewrite SyncPrimitiveUpgrade {
  type PRLock* => Mutex*
  call PR_NewLock() => new Mutex()
  call PR_Lock(lock) => lock->Lock()
  call PR_Unlock(lock) => lock->Unlock()
  call PR_DestroyLock(lock) => delete lock
}
因此,它找到了所有类型的PRLock,并用互斥重放它,还搜索函数调用
像PR_NewLock一样,用“new Mutex”替换它。

您可能希望研究C解析器。它了解很多C语言(Linux内核源代码中使用的所有C语言,它是合法ANSI-C和GNU-C扩展的一个相当好的子集),并提供了一些示例编译器后端,为类型检查提供了一个类似于静态分析工具的工具


虽然代码看起来非常干净和彻底,但通过另一种机制,您的任务可能会更容易完成——演示编译器的
稀疏
源代码中包含的
example.c
有1955行

对于C,您无法可靠地做到这一点。如果跳过预处理,一般来说,将无法解析有效的C代码。例如

#define FOO
#define BAR
#define BAZ

FOO void BAR qux BAZ(void) { }

解析器如何在不进行预处理的情况下识别qux的函数定义?

首先,GCC不是一个库,也不是一个库(与LLVM相反)

为什么要解析(C)、C++、艾达源代码?< /P>

我会考虑(假设GCC <强> 4.6版/强>版本)扩展GCC,或者通过C编写的插件,或者最好使用高级域特定语言来扩展GCC(免责声明:我是熔体的主要作者)。 但是使用GCC作为库是完全不现实的

我真的认为,对于你想要实现的目标,MELT是正确的工具。然而,这方面的记录却很少。请使用
gcc-melt@googlegroups.com
列出要提问的问题


请注意,扩展GCC确实需要一些工作(可能一周多),因为您需要部分了解GCC的内部表示

> P>忘记GCC,它是编译器的解析器,不是分析解析器,你可以用C接口来做更好的处理,它可以处理C+C++< /P> < P>我们可以在各种方言中解析C++、C++、java和艾达代码(不是目标C),并对代码进行转换。DMS的前端包括一个预处理器,因此您可以在解析之前进行预处理

我可能不明白您想做什么,因为用“My…”前缀重命名每个函数和(全局?)变量似乎很奇怪。但您可以使用一些DMS规则(GCC3用户函数重命名的草图:

domain C~GCC3.

rule rewrite_function_names(t: type_designator, i: IDENTIFIER, p: parameter_list, s: statements):
      function_header->functionheader
"\t \i(\p) { \s } " -> "\t \renamed\(\i\) (\p) { \s }" ;
辅助函数“重命名”,它接受包含标识符的树节点,并返回具有重命名标识符的树节点

因为DMS模式只与解析树匹配,所以不会得到任何误报

您需要一些额外的模式来处理每个语言中的各种不同语法情况(例如,对于C,“void”返回类型,因为“void”在语法中不是类型指示符,以及全局变量声明),以及不同语言的不同规则(Ada的语法与C的语法不同)

这对您的任务来说似乎是一个巨大的打击,但是如果您真的坚持以可靠的方式为各种语言执行此操作,那么似乎很难避免为所有这些语言获得合适的解析器的问题。(如果你真的要对所有这些语言这么做,可以教DMS处理ObjectiveC,就像我们教它处理其他语言一样)


您的替代方案是某种字符串黑客解决方案,它可能在95%的时间内都有效。如果您能够接受,那么Perl或类似的解决方案可能就是您的答案。

这是一个相当大的要求。您尝试了什么?您面临哪些具体问题?您是否阅读了gcc链上的手册页(无需预处理等)?此外,预处理可能不是让代码在程序内部工作所需的唯一步骤。您到底想做什么?我尝试过使用clang,但无法将其编译。我:不太擅长切割。gcc链是什么?我想跳过预处理,因为我不想在程序中使用头或宏文件。基本上我想做的是用前缀重命名函数和变量。啊,我的意思是说GCC工具链。这真的是比我应该使用的更广泛的术语。我应该只说GCC人页,也许链接人页面取决于你到底在做什么。你说你可以用Lua来做C++的PAR。sing?我不知道Lua,但如果它能工作的话,我会学习它。另外,我也读过GCC手册。通常当有人想要包含GCC时,他们只是试图为他们的项目制作附加组件,这用脚本语言做起来容易得多。如果你的目标是修改源代码,那么你会想要与GCC接口。我正在使用现在我的代码编译有问题,可能是我的系统太新了。或者你的系统太旧了。gcc的插件支持是在gcc 4.5中引入的,所以如果你的gcc版本<4.5…我的系统是Ubuntu11.10,带有gcc-3.3 gcc-3.4 gcc-4.0 gcc-4.2 gcc-4.3 gcc-4.4 gcc-4。6@Taylor:哪个是o特别是你有问题吗?很棒的代码>猪肉[/COD] >例子——没有什么比工作代码更简单。稀疏看起来不错,但它不支持C++支持。当然没有java。