2

我想计算关于 c++ 程序的“空行”、“单条注释”、“块注释”。

我写工具使用flex。但是工具不能匹配c++块注释。

1个弹性代码:

%{
    int block_flag = 0;
    int empty_num = 0;
    int single_line_num = 0;
    int block_line_num = 0;
    int line = 0;
%}

%%
^[\t ]*\n               {
    empty_num++;
    printf("empty line\n");
}
"//"    {
    single_line_num++;
    printf("single line comment\n");
}
"/*"  {
    block_flag = 1;
    block_line_num++;
    printf("block comment begin.block line:%d\n", block_line_num);
}

"*/"  {
    block_flag = 0;
    printf("block comment end.block line:%d\n", block_line_num);
}
^(.*)\n                 {
    if(block_flag)
    block_line_num++;
    else
    line++;
}

%%
int main(int argc , char *argv[])
{
    yyin = fopen(argv[1], "r");
    yylex();

    printf("lines :%d\n" ,line);
    fclose(yyin);

    return 0;
}

2 你好.c

bbg@ubuntu:~$ cat hello.c 
#include <stdlib.h>

//
//
/*
 */

/*   */

3 输出

bbg@ubuntu:~$ ./a.out hello.c 
empty line
empty line
lines :6

为什么“//”和“/*”不能匹配单个注释和块注释?

4

1 回答 1

4

柔性:

  1. 不搜索。它按顺序匹配模式,每个模式从另一个结束的地方开始。

  2. 总是选择匹配最长的模式。(如果两个或多个模式匹配的数量完全相同,它会选择第一个。

所以你有了

"//"   { /* Do something */ } 

^.*\n  { /* Do something else */ }

假设它刚刚匹配第二个,所以我们在一行的开头,假设该行开始//。现在,这两种模式都匹配,但第二个匹配整行,而第一个只匹配两个字符。所以第二个赢了。那不是你想要的。

提示 1:您可能希望//注释匹配到行尾

提示 2:有一个正则表达式可以匹配/*注释,虽然它有点乏味:"/*"[^*]*"*"+([^*/][^*]*"*"+)*"/"不幸的是,如果你使用它,它不会为你计算行尾,但你应该能够调整它来做你想做的事。

提示 3:您可能想考虑从一行中间开始的注释,可能已经缩进。您的规则^.*\n将吞下整行,甚至不查看其中是否有评论。

提示 4:字符串文字隐藏注释。

于 2012-10-24T02:54:48.397 回答