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. 常に最長一致のパターンを選択します。(2 つ以上のパターンがまったく同じ金額に一致する場合、最初のパターンが選択されます。

だから、あなたは持っています

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

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

2 番目のものとちょうど一致したと仮定して、行の先頭にいるとします。行が starts であるとします//。現在、これらのパターンは両方とも一致しますが、2 番目のパターンは行全体に一致しますが、最初のパターンは 2 文字のみに一致します。というわけで、2番手が勝ち。それはあなたが望んでいたものではありませんでした。

//ヒント 1: おそらく、コメントは行末まで一致させたいでしょう。

/*ヒント 2:少し面倒ですが、コメントに一致する正規表現があります:"/*"[^*]*"*"+([^*/][^*]*"*"+)*"/"残念ながら、それを使用すると、行末はカウントされませんが、必要に応じて適応させることができるはずです。

ヒント 3: インデントされている可能性がある、行の途中から始まるコメントについて考えたいと思うかもしれません。^.*\n行内のどこかにコメントがあるかどうかを確認することさえせずに、行全体を飲み込むルールを作成します。

ヒント 4: 文字列リテラルはコメントを隠します。

于 2012-10-24T02:54:48.397 に答える