找到一个函数名并计算其LOC

时间:2009-05-31 06:34:16

标签: c++ string

所以你知道了,这是我被分配的项目。我不是在寻找代码中的答案,而是更多的方向。

我被告知要做的是查看文件并计算实际的代码行,同时记录函数名称和函数的各行代码。我遇到的问题是从文件读取时确定一种方法,以确定该行是否是函数的开头。

到目前为止,我只能想到可能有一个数据类型的字符串数组(int,double,char等),在行中搜索,然后搜索括号,然后搜索不存在的数据类型分号(所以我知道它不仅仅是函数的声明)。

所以我的问题是,这是我应该如何解决这个问题,还是有其他方法可以推荐?

我将计算的代码将使用C ++。

6 个答案:

答案 0 :(得分:7)

我想到了三种方法。

  1. 使用正则表达式。这与您的想法非常相似。寻找看起来像函数定义的行。这样做很快,但在很多方面都可能出错。

    char *s = "int main() {"
    

    不是函数定义,但确实看起来像一个。

    char
    * /* eh? */
    s
    (
    int /* comment? // */ a
    )
    // hello, world /* of confusion
    {
    

    是一个函数定义,但看起来不像。

    好:写得快,即使面对语法错误也能正常工作;坏:很容易在看起来像(或看起来不像)“正常”的情况下惹火。

    变体:首先运行代码,例如,GNU缩进。这将解决一些(但不是全部)失火问题。

  2. 使用适当的词法分析器和解析器。这是一种更彻底的方法,但您可以重新使用开源词法分析器/解析(例如,从gcc)。

    好:将100%准确(永远不会失火)。坏:一个丢失的分号,它会出现错误。

  3. 查看您的编译器是否有一些可能有帮助的调试输出。这是(2)的变体,但使用编译器的词法分析器/解析器而不是您自己的。

答案 1 :(得分:4)

您的想法可以在99%(或更多)的案例中发挥作用。只有真正的C ++编译器可以100%执行,在这种情况下我将以调试模式(g++ -S prog.cpp)进行编译,并从程序集输出的调试信息中获取函数名称和行号(prog.s )。

我对99%解决方案的看法:

  • 忽略评论和字符串。
  • 您忽略预处理程序指令的文档(#include#define#if)。
  • 顶级{}之间的任何内容都是函数正文,但typedef之后,classstructunion,{ {1}}和namespace
  • 如果您有enumclassstruct,则应该在其中寻找方法主体。
  • 函数名称有时很难找到,例如在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计划。