Next: , Previous: More Examples, Up: More Examples


7.1 単語数、文字数、行数のカウント

以下の定義は、 与えられたファイルの中の単語数、文字数、行数をカウントするのにFlexを使う方法を示す、 簡単な例です。 実際にFlexに関係のある部分は、 非常に少ないことに注意してください。 以下のコードのほとんどは、 コマンドライン・パラメータを処理したり、 カウントの合計を保持したりするものです。

     
     
     
     
     /*
      * wc.lex : wcのようなユーティリティを、
      *          Flexを使って作成する簡単な例
      */
     
     %{
     int  numchars = 0;
     int  numwords = 0;
     int  numlines = 0;
     int  totchars = 0;
     int  totwords = 0;
     int  totlines = 0;
     %}
     
     
     
     /*
      * ルールはここから始まる
      */
     
     %%
     
     [\n]        { numchars++;  numlines++;         }
     [^ \t\n]+   { numwords++;  numchars += yyleng; }
     .           { numchars++;                      }
     %%
     
     
     
     
     
     /*
      * 追加的なCコードがここから始まる。
      * ここで、すべての引数処理等を行うコードが提供される
      */
     void main(int argc, char **argv)
     {
       int  loop;
     
     
     
     
       int  lflag = 0; /* 行数をカウントする場合は1         */
       int  wflag = 0; /* 単語数をカウントする場合は1       */
       int  cflag = 0; /* 文字数をカウントする場合は1       */
       int  fflag = 0; /* ファイル名が指定されている場合は1 */
       for(loop=1; loop<argc; loop++){
          char *tmp = argv[loop];
          if(tmp[0] == '-'){
          switch(tmp[1]){
            case 'l':
               lflag = 1;
               break;
            case 'w':
               wflag = 1;
               break;
            case 'c':
               cflag = 1;
               break;
            default:
               fprintf(stderr,"unknown option -%c\n",tmp[1]);
          }
         } else {
           fflag = 1;
           numlines = numchars = numwords = 0;
           if((yyin = fopen(tmp,"rb")) != 0){
             (void) yylex();
             fclose(yyin);
             totwords += numwords;
             totchars += numchars;
             totlines += numlines;
             printf("file  : %25s :",tmp) ;
             if(lflag){
               fprintf(stdout,"lines %5d ",numlines);
             }
             if(cflag){
               fprintf(stdout,"characters %5d ",numchars);
             }
             if(wflag){
               fprintf(stdout,"words %5d ",numwords);
             }
             fprintf(stdout,"\n");
           }else{
             fprintf(stderr,"wc : file not found %s\n",tmp);
           }
         }
       }
       if(!fflag){
         fprintf(stderr,"usage : wc [-l -w -c] file [file...]\n");
         fprintf(stderr,"-l = count lines\n");
         fprintf(stderr,"-c = count characters\n");
         fprintf(stderr,"-w = count words\n");
         exit(1);
       }
       for(loop=0;loop<79; loop++){
         fprintf(stdout,"-");
       }
       fprintf(stdout,"\n");
       fprintf(stdout,"total : %25s  ","") ;
       if(lflag){
         fprintf(stdout,"lines %5d ",totlines);
       }
       if(cflag){
         fprintf(stdout,"characters %5d ",totchars);
       }
       if(wflag){
          fprintf(stdout,"words %5d ",totwords);
       }
       fprintf(stdout,"\n");
     }