从c ++文件中提取信息

时间:2014-07-21 09:20:47

标签: c++ parsing

我知道这个问题一定有点不清楚,但我会尽力解释我的需求。

首先,我从1年开始就是一名学徒开发人员,我正在实习,而我的老板要我根据代码创建文档生成器。

基于代码的文档生成器?

文档生成器是一个读取c ++文件的程序,从这个c ++文件中检索包括声明的变量和函数在内的最大信息,并以人类可读的格式(表格)显示它们。

示例:

#include <iostream>

using namespace std;

int returnANumber(int argNumber)
{
    int i = 0;
    i = argNumber;
    return argNumber;
}

int main()
{
    returnANumber(70);

    return 0;
}

这是程序将读取的c ++文件示例,并检索所有信息,在这种情况下函数的名称(returnANumber),变量(i),using指令(iostream)。

作为第一种方法,我想使用REGEX,并匹配例如:

data-type word ( data-type word);

带有函数声明,但有很多情况需要管理,例如在静态类中声明方法...:

data-type static word (data-type word);

这里的REGEX是一个非常难的解决方案,如果有其他解决方案可以使用我担心吗?任何帮助?

提前感谢。

1 个答案:

答案 0 :(得分:2)

您所述的问题似乎要求您自己阅读C ++源文件,并提取文档。通常,这是不可能的:C ++允许宏,它实际上可以对原始文本进行任意编辑,以生成有效的C ++源代码。 C ++还允许#include指令,它可以获取准确解释类型所需的其他信息。面对这些,你无法提取好的信息。

所以你有两个选择:

  • &#34;解析&#34;单个文件并提取您可以面对的这些问题。我使用&#34;解析&#34;在这里,因为程序源本身在宏和包含的情况下不是有效的C ++。在这种情况下,正则表达式可能会做到你希望的那样。不要指望它做得好; C ++是一种非常难以解析的语言,正则表达式不能处理无上下文的解析,因此这个方案中的漏洞将是无穷无尽的痛苦。 [Doxygen用作默认值&#34;糟糕的解析&#34;要对许多语言进行此类解析,请参阅下面的其他说明](如果您坚持在此路径上,我们的DMS软件重组工具包可能会有所帮助:它可以是配置为将源文件解析为一系列有效的语言子串,从而可以读取格式不正确的文件。即使使用此文件也很难获取类型信息。

  • 按照编译器的方式解析单个文件,使用完整的预处理功能以编译器真正看到它的方式获取程序文本。这需要工具来处理所有预处理程序指令,包括编译器命令行上找到的任何(通常)指令。编译器构建完整的符号表,其中包含您要提取的信息。为此,您需要具有完整编译器前端的东西。你自己没有精力建立一个。

后者的一些选择是:

  • 锵/ LLVM
  • 爱迪生设计集团(EDG)C ++前端
  • 我们的DMS软件再造工具包。
  • GCC(可能是衍生工具GCCXML)

设置其中的每一项,并提取您想要的信息,是一项非常重要的工作。要直接使用它们,您必须对每个工具以及一般的编译器技术(解析,符号表)了解很多,然后您必须在这些工具内部提供的生态系统中自定义代码。如果您不熟悉它们,可能需要花费很长时间才能学习。

Clang / LLVM是OSS,用C ++编写。我不知道它如何处理微软的C ++方言。我的理解是Doxygen现在使用Clang处理C ++源代码;这可能是获取此信息的最简单方法,尤其是如果您想要的只是&#34;某些文档&#34;已经预先格式化了。但是,这违反了你的#34;从头开始构建工具&#34;格言。

EDG是一个商业前端,广泛用于许多生产C ++编译器。它可用于研究(也许你正在做的事情可归类为,但如果你是商业装,我怀疑它);我认为它是用C编码的。

DMS是商业用途,但有研究许可证选项;编码是在涉及BNF,属性语法和并行编程语言PARLANSE的领域特定语言的组合中完成的。 DMS通过C ++ 11和大多数C ++ 14处理C ++的GCC和MS方言。

GCC是用C语言编写的,但实际上,我真的很想成为编译器,并且会拒绝你将它弯曲到你的目的。然而,其他人以前一直在使用GCC,并在顶部构建了GCCXML,它至少可以提取一些你想要的信息作为XML文件;如果您希望以可以操作的形式轻松获取信息,那么这可能是您最好的选择。