如何在大型C ++源代码树中找到所有相互的友谊?

问题描述 投票:1回答:4

在一个大型C ++源代码树中,定义了大约600个类,我希望找到所有类,其中每个类都声明另一个朋友。

很多情况下,一个班级是另一个班级的朋友,太多的情况下不值得通过一个简单的grep结果。

c++ class friend
4个回答
2
投票

你可以在这里实现一种三重循环;算法可以如下:

  1. 第一个循环:找到所有有朋友的班级,并记住朋友的名字和实际班级的名字;
  2. 然后为所有类运行内部循环,并从步骤1中找到具有该朋友名称的类。
  3. 然后在步骤2中找到的所有班级朋友中运行另一个内循环。如果你从第1步找到了名字的班级 - 瞧 - 他们是共同的朋友。

我相信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比较什么?


2
投票

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。


1
投票

这个答案类似于@ user534498,但我会详细介绍一下,因为“使用正则表达式解析C ++”的建议是如此疯狂,我认为不值得考虑。

我也不认为你会找到一个可以为你做这个的自动化工具。如果这是托管代码的土地,我会建议像Nitriq这样的东西,但我不认为这样的东西适用于C ++。

如果您不担心嵌套类,我认为您可以毫不费力地为朋友构建课程。您可以找到关键字类的实例,后跟花括号,在花括号中查找友元语句。这应该没有太多困难,列出哪些课程有哪些朋友。

完成后,您可以轻松检查重复的引用。 (取决于您使用的语言...如果您使用的是C ++,那么您将结果放在std::multimap中,其中键是类名,值是朋友)

我想这与@Haspemulator建议的类似......但我的观点是,拆分解析可能更容易,然后根据集合或映射实现循环引用检查,那么它将尝试交织这些操作。


-1
投票

使用perl或python或c ++正则表达式来解析所有文件,记录所有类 - 朋友对。这些600对的匹配应该是微不足道的

© www.soinside.com 2019 - 2024. All rights reserved.