所以你知道了,这是我被分配的项目。我不是在寻找代码中的答案,而是更多的方向。
我被告知要做的是查看文件并计算实际的代码行,同时记录函数名称和函数的各行代码。我遇到的问题是从文件读取时确定一种方法,以确定该行是否是函数的开头。
到目前为止,我只能想到可能有一个数据类型的字符串数组(int,double,char等),在行中搜索,然后搜索括号,然后搜索不存在的数据类型分号(所以我知道它不仅仅是函数的声明)。
所以我的问题是,这是我应该如何解决这个问题,还是有其他方法可以推荐?
我将计算的代码将使用C ++。
答案 0 :(得分:7)
我想到了三种方法。
使用正则表达式。这与您的想法非常相似。寻找看起来像函数定义的行。这样做很快,但在很多方面都可能出错。
char *s = "int main() {"
不是函数定义,但确实看起来像一个。
char
* /* eh? */
s
(
int /* comment? // */ a
)
// hello, world /* of confusion
{
是一个函数定义,但看起来不像。
好:写得快,即使面对语法错误也能正常工作;坏:很容易在看起来像(或看起来不像)“正常”的情况下惹火。
变体:首先运行代码,例如,GNU缩进。这将解决一些(但不是全部)失火问题。
使用适当的词法分析器和解析器。这是一种更彻底的方法,但您可以重新使用开源词法分析器/解析(例如,从gcc)。
好:将100%准确(永远不会失火)。坏:一个丢失的分号,它会出现错误。
查看您的编译器是否有一些可能有帮助的调试输出。这是(2)的变体,但使用编译器的词法分析器/解析器而不是您自己的。
答案 1 :(得分:4)
您的想法可以在99%(或更多)的案例中发挥作用。只有真正的C ++编译器可以100%执行,在这种情况下我将以调试模式(g++ -S prog.cpp
)进行编译,并从程序集输出的调试信息中获取函数名称和行号(prog.s
)。
我对99%解决方案的看法:
#include
,#define
,#if
)。{
和}
之间的任何内容都是函数正文,但typedef
之后,class
,struct
,union
,{ {1}}和namespace
。enum
,class
或struct
,则应该在其中寻找方法主体。union
。答案 2 :(得分:3)
对于录制功能名称,我使用PCRE和正则表达式
"(?<=[\\s:~])(\\w+)\\s*\\([\\w\\s,<>\\[\\].=&':/*]*?\\)\\s*(const)?\\s*{"
然后过滤掉“if”,“while”,“do”,“for”,“switch”等名称。请注意,函数名称为(\ w +),组1。
当然,这不是一个完美的解决方案,而是一个很好的解决方案。
答案 3 :(得分:2)
找到一个像样的SLOC计数程序,例如SLOCCounter。您不仅可以计算SLOC,还可以使用某些东西来比较您的结果。 (更新:这里有long list个。)
有趣的是,C / C ++程序中非注释分号的数量是一个不错的SLOC计数。
答案 4 :(得分:2)
我觉得手动进行解析将是一项相当困难的任务。我可能会使用现有工具,例如RSM将输出重定向到csv文件(假设您在Windows上),然后解析csv文件以收集所需信息。
答案 5 :(得分:2)
如何编写shell脚本来执行此操作?也许是一个AWK计划。