是否有任何工具可以解析c头文件并从c头文件中提取函数原型

时间:2011-06-09 08:17:56

标签: c parsing code-generation

特别是获取函数返回类型(如果可能的话,是否为指针类型)。

(我正在尝试编写ioctl / dlsym包装器库的自动生成(为LD_PRELOAD编辑))。将首选python或ruby库,但欢迎使用任何可行的解决方案。

4 个答案:

答案 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:llvm架构上相当完整的C实现,支持大多数gcc扩展。很容易从C代码生成AST。您可以将clang编译为lib并直接使用AST,或将clang二进制文件转储到stdout。
  • gcc(我个人跟clang一起去;更清洁)。
  • Antlr(解析器生成器; c的许多现有解决方案都在互联网上浮动)。

答案 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前端使用。