特别是获取函数返回类型(如果可能的话,是否为指针类型)。
(我正在尝试编写ioctl / dlsym包装器库的自动生成(为LD_PRELOAD编辑))。将首选python或ruby库,但欢迎使用任何可行的解决方案。
答案 0 :(得分:5)
我已成功使用来自hackage的Haskells Language.C包(Haskells回答CPAN)来做类似的事情。它将为您提供C(或头文件)文件的完整解析树,然后可以遍历该文件以提取所需信息。 AFAIK也应该与#include
s #define
s一起使用,等等。
我担心我没有安装相关软件来测试它,但它会是这样的:
handler (DeclEvent (Declaration d)) =
do
let (VarDecl varName declAttr t) = getVarDecl d
case t of
(FunctionType (FunType returnType params isVaradic attrs)) ->
do {- varName RETURNS returnType .... -}
_ -> do return ()
return ()
handler _ =
do return ()
main = do
let compiler = newGCC "gcc"
ast <- parseCFile compiler Nothing opts cFileName
case (runTrav newState (withExtDeclHandler (analyseAST ast) handler)) of
...
上面的内容可能看起来很吓人,但你可能不会需要更多的Haskell来做你想做的事!我很乐意分享我使用过的完整源代码(约200行),如果有任何帮助的话。
答案 1 :(得分:4)
您正在寻找的是一种轻松生成Abstract Syntax Tree任意c代码的方法。为此(如果你熟悉python),我建议使用pycparser:
parser = CParser()
buf = '''
static void foo(int k)
{
j = p && r || q;
return j;
}
'''
t = parser.parse(buf, 'x.c')
t.show()
产生
FileAST:
FuncDef:
Decl: foo, [], ['static']
FuncDecl:
ParamList:
Decl: k, [], []
TypeDecl: k, []
IdentifierType: ['int']
TypeDecl: foo, []
IdentifierType: ['void']
Compound:
Assignment: =
ID: j
BinaryOp: ||
BinaryOp: &&
ID: p
ID: r
ID: q
Return:
ID: j
每个编译器都这样做,并且大多数编译器都提供api来访问各种解析/语义检查例程。此外,任何常用的解析器生成器都应该有可用于解析c的语法。如果你担心表现和/或想留在c里,我建议你看看:
clang
二进制文件转储到stdout。答案 2 :(得分:3)
cproto
程序执行此操作。请注意,有两个单独的版本:
直到最近,GCC还包括一个可以完成这项工作的程序protoize
(并将K&amp; R函数定义转换为ISO原型函数定义);但是,这不再是GCC发行的一部分。
答案 3 :(得分:2)
我们的DMS Software Reengineering Toolkit及其C Front End很容易就能做到这一点。
DMS使用语言定义(在本例中为C语言)来解析源代码,构建抽象语法树,确定表达式类型并构建完整的符号表。它还可以将AST重新打印回有效的语言文本(例如,C代码)。您可以轻松找到函数声明,并从符号表条目中收集您想要的任何内容(“返回类型是指针吗?”),和/或将声明打印为原型。如果要打印出实际上不依赖于实际文件中其他定义的原型,您可能会发现需要规范化符号;这需要为各种类型的声明构建AST并将它们替换为彼此。我们过去已经为其他客户做过这个,这个机器可以在C前端使用。