在一个大型C ++源代码树中,定义了大约600个类,我希望找到所有类,其中每个类都声明另一个朋友。
很多情况下,一个班级是另一个班级的朋友,太多了,不值得趟过一个简单的grep结果。
答案 0 :(得分: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 :(得分:2)
你可以在这里实现一种三重循环;算法可以如下:
我相信Perl和regex是这类事情的最佳工具。
P.S。确定这种方法有其局限性,因为并非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 :(得分:1)
这个答案类似于@ user534498,但我会详细介绍一下,因为“用正则表达式解析C ++”的建议是如此疯狂,我认为不值得考虑。
我也认为你不会找到一个可以为你做这个的自动化工具。如果这是托管代码,我会建议像Nitriq这样的东西,但我不认为这样的东西适用于C ++。
如果您不担心嵌套类,我认为您可以毫不费力地为朋友构建课程。您可以找到关键字类的实例,后跟花括号,在花括号中查找友元语句。这应该没有太多困难,列出哪些课程有哪些朋友。
完成后,您可以轻松检查重复的引用。 (取决于您使用的语言...如果您使用的是C ++,那么您将结果放在std::multimap
中,其中键是类名,值是朋友)
我想这与@Haspemulator建议的类似......但我的观点是,拆分解析可能更容易,然后根据集合或映射实现循环引用检查,然后它将是试图将这些行动交织在一起。
答案 3 :(得分:-1)
使用perl或python或c ++ regex解析所有文件,记录所有的class-friends对。对于这类600对
,匹配应该是微不足道的