2012-01-18 70 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