在一个大型C ++源代码树中,定义了大约600个类,我希望找到所有类,其中每个类都声明另一个朋友。
很多情况下,一个班级是另一个班级的朋友,太多的情况下不值得通过一个简单的grep结果。
你可以在这里实现一种三重循环;算法可以如下:
我相信Perl和regex是这类事情的最佳工具。
附:确定这种方法有其局限性,因为并非C ++中的所有内容都可以用正则表达式进行解析(using namespace
的东西是我脑子里想到的第一件事)。但是,在某种程度上,这是一种工作方法,如果你没有其他选择,你可以尝试一下。
EDIT:
今天早上我想到了一个想法,而我仍躺在床上。 :)这个想法非常简单明了(就像所有早上的想法一样):使用SQL!当然,假设您有一个包含2列的类表,其中第一列是类名,第二列是它的朋友名。说,像这样:
ClassName FriendName
C1 C2
C1 C3
C1 C4
C2 C1
C2 C8
C3 C1
C3 C2
... ...
然后你可以对它运行一个简单的查询。说,这样的事情(抱歉,我没有任何SQL DB方便,所以没有检查查询,但我希望你能得到这个想法,并根据需要实现它:
SELECT ClassName as c, FriendName as f FROM T
WHERE c in
(SELECT FriendName FROM T
WHERE FriendName = c AND ClassName = f)
这种变体背后的想法是我们应该使用那些完全符合任务的收费。当你需要处理一些数据集时,可以与SQL比较什么?
I)一些优雅的方式:
1)Doxygen(http://www.doxygen.nl/)可能能够满足您的需求。 (如果它还没有提供这些信息,你可以稍微破解Doxygen的C ++解析器来获得你需要的东西)。
2)也存在C ++的ANTLR语法文件。
II)更快的方式(也许这里是正确的方法):
正如其他人所说,正则表达式应该适合您的目的。请考虑以下伪代码:
rm -f result_file;
foreach source_file
do
sed 's/[ \t\n]\+/ /g' $source_file > temp_file; ## remove newlines, etc
grep -o -P -i "friend [^;]*;" >> result_file; ## you can improve this regex for eliminating some possible unwanted matches or post-process result_file later
done
现在你在result_file中拥有所有朋友关系。您可以使用另一个简单的正则表达式删除“朋友函数”和/或根据需要进一步处理result_file。
这个答案类似于@ user534498,但我会详细介绍一下,因为“使用正则表达式解析C ++”的建议是如此疯狂,我认为不值得考虑。
我也不认为你会找到一个可以为你做这个的自动化工具。如果这是托管代码的土地,我会建议像Nitriq这样的东西,但我不认为这样的东西适用于C ++。
如果您不担心嵌套类,我认为您可以毫不费力地为朋友构建课程。您可以找到关键字类的实例,后跟花括号,在花括号中查找友元语句。这应该没有太多困难,列出哪些课程有哪些朋友。
完成后,您可以轻松检查重复的引用。 (取决于您使用的语言...如果您使用的是C ++,那么您将结果放在std::multimap
中,其中键是类名,值是朋友)
我想这与@Haspemulator建议的类似......但我的观点是,拆分解析可能更容易,然后根据集合或映射实现循环引用检查,那么它将尝试交织这些操作。
使用perl或python或c ++正则表达式来解析所有文件,记录所有类 - 朋友对。这些600对的匹配应该是微不足道的