计算代码行数

Counting lines of code

本文关键字:代码 计算      更新时间:2023-10-16

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

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

在它的sourceforge页面,你可以找到perl源代码下载。

好吧,如果行计数器是指计算行的程序,那么算法非常简单:只需'n'计算法典。 另一方面,如果您指的是C++语句,或生成其他指标... 虽然不是100%准确,过去,我仅通过计算"}"和';'(忽略注释以及字符串和字符文字中的那些,当然)。 任何更准确的内容都可能需要解析实际C++。

您不需要实际解析代码来计算行号,只需对其进行标记即可。

该算法可能如下所示:

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++,尤其具有挑战性。然而,标记化(或"词法"或"词法分析")更容易,特别是当你不关心太多细节时,你应该能够使用有限状态机自己编写一个分词器。

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

我认为人们在理解你的问题时遇到如此多麻烦的部分原因是因为"计算c ++的行数"本身就是一种算法。也许你想问的是"如何识别文件中的一行 c++?这是一个完全不同的问题,科斯似乎在试图解释方面做得很好。