有各种各样的工具可以用来计算源文件或目录树(例如cloc
)中的代码行数,也有一些工具可以用来计算纯文本文件(wc
)中的字数。
但是,我该如何计算代码中的单词或标记呢?如果不编写一个成熟的程序,使用一些通用的编程语言解析机制(如tree-sitter),这是否可行呢?更具体地说,我可以使用shell工具或简单的脚本来完成吗?
注意:只有注解以外的单词/标记必须计算在内。对于一般的单词计数,我肯定还有其他问题...
示例:假设我的代码是用C语言编写的,并且foo.c
文件包含
int /* this is
a multi-line
comment!
*/
foo(int x) {
/* comment 1 */
return 123; // comment 2
}
这里期望的确切数目取决于我们是否将大括号和分号视为要计数的单词/标记。如果我们这样做,那么这应该是11个标记:int
,foo
,(
,int
,x
,)
,{
,return
,123
,;
,}
.如果我们忽略它们(我不想这样,但这仍然可能是一个合法的方法),那么我们有6个词:一米十四个一英寸、一米十五个一英寸、一米十六个一英寸、一米十七个一英寸、一米十八个一英寸、一米十九个一英寸。
2条答案
按热度按时间db2dz4w81#
编辑,我的错,我离开了@Gilles示例,错过了注解部分。根据您使用C/C ++注解并忽略
/*
和*/
之间的多行注解的示例,每行非注解标记可以使用计数器tokens
和标志skip
通过检查字段是否包含在"//"
上来获得。"/*"
或"*/"
,因为您会在每个标记周围显示空白。将文件处理为非注解空白分隔标记的简单awk
脚本可以是:(note:解析C语言中包含非witespace的单个标记,例如
"foo(int"
未被寻址。如果需要在该级别进行解析,则使用awk
重新创建轮子可能不是您的最佳选择。但是添加条件以忽略仅由(,{,[
或],},)
组成的字段是很容易做到的。)单个规则迭代每个字段并检查开始注解。对于
"//"
,该行的其余部分将被忽略。对于"/*"
,将设置skip
标志,并且在该行中遇到结束"*/"
之前不再计数标记。修改的示例文件:
如果你把你的
awk
脚本命名为noncmttokens.awk
,并使用chmod +x noncmttokens.awk
使其可执行,那么你所需要做的就是把file
作为参数来运行它,例如:很抱歉忽略了问题中的评论赘言,我使用了另一个答案中的示例文件--发生了...
split
**要将文件处理为所需的标记,同时保持所有注解打开/关闭都是空格分隔的,并且只在
"("
上拆分非空格分隔的标记,您可以执行以下操作:使用
file2.c
中提供的示例文件,例如将该文件作为参数提供给扩展的
awk
脚本,您将得到:awk
可以高效地处理您需要做的任何事情,但正如评论中提到的,我怀疑随着更多细节的添加,它将成为一项更多的工作,重新发明编译器在其编译级别之一所做的事情。这种标记的拆分是基本的,但需要处理的极端情况的数量,例如处理混淆的C/C ++代码的需求迅速地呈指数增长。希望这能提供你所需要的。
qpgpyjmq2#
文件
考虑下面这个简单的perl代码片段:
使用bash:
使用grep:
使用awk: