计算代码行

时间:2012-07-04 15:14:15

标签: c++ lines-of-code

我正在为C ++项目的行计数器做一些研究,我对他们使用的算法非常感兴趣。有谁知道我在哪里可以看到这些算法的一些实现?

4 个答案:

答案 0 :(得分:18)

cloc,这是一个免费的开源代码计数器源代码行。它支持多种语言,包括C ++。我个人用它来计算我项目的行数。

sourceforge页面,您可以找到要下载的perl源代码。

答案 1 :(得分:3)

好吧,如果通过行计数器,你的意思是计算行数的程序,那么 算法非常简单:只计算'\n'的数量 码。另一方面,如果你指的是计算C ++的程序 陈述,或产生其他指标......虽然不是100%准确, 我过去得到了相当不错的结果只是计算'}'和 ';' (忽略评论和字符串和字符文字中的那些 课程)。任何更准确的东西都可能需要解析 实际的C ++。

答案 2 :(得分:2)

您不需要实际解析代码来计算行号,这足以标记它。

算法可能如下:

int lastLine = -1;
int lines = 0;
for each token {
    if (isCode(token) && lastLine != token.line) {
        ++lines; 
        lastLine = token.line;
    }
}

在令牌化期间您需要收集的唯一信息是:

  • 它是什么类型的令牌(运算符,标识符,注释......)实际上你不需要在这里得到非常精确,因为你只需要区分“非代码令牌”(评论)和“代码令牌”(其他任何东西)
  • 令牌发生在文件中的哪一行。

关于如何标记,这是你要弄清楚的,但为这样一个简单的案例手写一个标记器应该不难。您可以使用flex,但这可能是多余的。


修改

我已经提到过“令牌化”,让我快速为您描述一下:

令牌化是编译的第一阶段。标记化的输入是文本(多行程序),输出是“标记”的序列,如:具有某种含义的符号。例如,以下程序:

#include "something.h"

/*
This is my program.
It is quite useless.
*/
int main() {
    return something(2+3); // this is equal to 5
}

看起来像:

PreprocessorDirective("include")
StringLiteral("something.h")
PreprocessorDirectiveEnd
MultiLineComment(...)
Keyword(INT)
Identifier("main")
Symbol(LeftParen)
Symbol(RightParen)
Symbol(LeftBrace)
Keyword(RETURN)
Identifier("something")
Symbol(LeftParen)
NumericLiteral(2)
Operator(PLUS)
NumericLiteral(3)
Symbol(RightParen)
Symbol(Semicolon)
SingleLineComment(" this is equal to 5")
Symbol(RightBrace)

等等。

令牌,根据其类型,可能附加任意元数据(即符号类型,运算符类型,标识符文本,或者可能是找到令牌的行号)。

然后将这样的令牌流提供给解析器,解析器使用根据这些令牌编写的语法生成规则,例如,构建语法树。

执行一个完整的解析器可以为您提供完整的代码语法树,这是一项具有挑战性的解决方案,如果我们正在谈论的是C ++,那么这个解析器尤其具有挑战性。然而,令人信服(或“lexing”或“词法分析”)更容易,尤其是。当你不关心很多细节时,你应该能够使用Finite state machine自己编写一个令牌器。

关于如何实际使用输出来计算代码行(即至少“代码”标记,即除了注释之外的任何标记开始的行) - 请参阅我之前描述的算法。

答案 3 :(得分:2)

我认为人们在理解你的问题时遇到很多麻烦的部分原因是因为“计算c ++的行数”本身就是算法。也许您要问的是“我如何识别文件中的一行c ++?”这是一个完全不同的问题,科斯似乎已经做了很好的解释。