2012-01-18 96 views
4

我现在正在研究问题,它的语句 - 生成带有.CPP文件中所有声明的全局变量列表的文本文件。从C++源文件创建全局变量列表

我想出了几个想法,第一个:

尝试使用CTAGS,所以我写了一些简短的脚本:

while read line 
do 
echo $line 
printf "%s" $line >> report.txt 
ctags -x --c++-kinds=v --file-scope=no "{$line}" | sort | sed "/const/d" | awk '{printf " %s", $1}' >> report.txt 
printf "\n" >> report.txt 
done < cpp_source_file_list.txt 

这段代码获取的.cpp源文件的文件名从cpp_source_file_list txt文件,扫描它的全局变量(忽略常数)和写报告“的文件名[变量列表。 我遇到的主要问题是,ctags的行为非常奇怪在某些情况下,STL类型忽略。

例如,它可以排除行ike“vector v;”,但包含“std :: vector v;”。

有什么方法可以解决这个问题吗?尝试使用ctags -I ./id.txt附加键并手动创建要覆盖的标识符列表,但它也会带来不正确的结果。

第二种方式:

使用nm命令,如:

nm builtsource.o | grep '[0-9A-Fa-f]* [BCDGRS]' 

但在这种情况下,我收到不必要的信息,如:

0000000000603528 B M 
0000000000603548 B N 
0000000000603578 B [email protected]@GLIBCXX_3.4 <- (!) 
0000000000603579 B [email protected]@GLIBCXX_3.4 <- (!) 
0000000000603748 B t 

现在我不知道如何以使这些方法中的一种从任意.cpp源文件中获得有关已声明全局变量列表的正确信息。我很乐意听到关于这个问题的任何建议。

+2

C++是“很难”解析的,所以使用像ctags这样的外部工具是必要的。然而,'const'的sedding不会让你接近忽略const global,它可以是const的非const指针,甚至可以是像'constant'这样的名字。 – Kos 2012-01-18 12:08:31

+0

当然,我同意关于sedding正则表达式,这是一种天真的解决方案。 – Twd1024 2012-01-18 12:12:37

+0

你会在家里有一个很好的C++解析器,它可以给你一个完整的AST。 Eclipse CDT有一个体面的解析器,但它不是独立工作的(因为我无法理解)。您必须使Eclipse插件才能使用它。我想知道使用GCC或Clang的内部结构生成AST是多么困难 – Kos 2012-01-18 12:15:03

回答

0

另一种可能性是开发一个GCC插件或一个MELT扩展名用于这个确切的目的。你需要了解一些GCC内部表示的细节(Gimple和Tree)。

自定义GCC(带有C或MELT中的扩展插件)的优点是您可以在预编译和解析之后处理确切的编译器内部。但是,这会花费你一些努力。

0

您可能会考虑使用GCC-XML,可能与顶部的其他东西(如pygccxml)相比,以便更容易浏览。我已经成功地将这个组合用于类似的代码提取目的。

1

您可能可以利用Doxygen来执行此操作。 Doxygen可以解析C++文件并生成一个XML文件,该文件捕获文件中遇到的所有变量。特别是,如果你设置以下配置选项:

EXTRACT_ALL= YES 
GENERATE_TAGFILE= doxygen.tag 

给予相同的输入文件:

#include <vector> 

using namespace std; 

std::vector<int> s1; 
vector s2; 

可以产生输出doxygen.tag文件,内容如下:

<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?> 
<tagfile> 
    <compound kind="file"> 
    <name>input.cpp</name> 
    <path>C:/Users/haney/tmp/tmp55/</path> 
    <filename>input_8cpp</filename> 
    <namespace>std</namespace> 
    <member kind="variable"> 
     <type>std::vector&lt; int &gt;</type> 
     <name>s1</name> 
     <anchorfile>input_8cpp.html</anchorfile> 
     <anchor>93b3bd32f5b6bff31bc4052716ddd444</anchor> 
     <arglist></arglist> 
    </member> 
    <member kind="variable"> 
     <type>vector</type> 
     <name>s2</name> 
     <anchorfile>input_8cpp.html</anchorfile> 
     <anchor>8feb4a508135e43a72f227568b755a07</anchor> 
     <arglist></arglist> 
    </member> 
    </compound> 
    <compound kind="namespace"> 
    <name>std</name> 
    <filename>namespacestd.html</filename> 
    </compound> 
</tagfile> 

一旦你有XML文件,你应该能够提取出你正在寻找的信息。

+0

谢谢你提供了很好的工作解决方案。有没有办法让Doxy不打印出“kind”属性与“file”或“variable”不同的块?有些情况下,当你得到大量的块与成员类等于“功能”,“typedef”等,这将是很好的摆脱.tag文件中的这些。 – fyodorananiev 2012-05-24 17:02:49

+0

请注意,大家:Doxygento识别变量声明为“int a(0);”作为“a”与“(0)”的函数。 – fyodorananiev 2012-05-24 19:42:38