Next: , Previous: Handling Numbers, Up: Useful Code


9.4 複数のスキャナ

時には、 1つのプログラムの中で複数のスキャナを持つ必要がある場合がありますが、 こうすると、 2回以上現れる関数や変数について、 リンカが文句を言ってきます。 これを回避するためには、 スキャナとそれに関連するすべてのものの名前を変更する必要があります。 すべてのスキャナ関数、マクロ、およびデータの名前は‘yy’もしくは‘YY’で始まりますので、 これはきわめて簡単です。 しなければならないことは、 名前の接頭辞を変更することだけです。 これはsedを使って簡単に行うことができますが、 ここではおもしろ半分で、 これを行うflexスキャナを示しましょう。1

     
     
     
     
     
     /*
      * replace.lex : flexにより生成されたスキャナや
      *               bisonにより生成されたパーサの
      *               一部の名前を変更する簡単なフィルタ
      */
     
     %{
     #include <stdio.h>
     
     char lower_replace[1024];
     char upper_replace[1024];
     
     %}
     %%
     
     "yy"   fprintf(yyout,"%s",lower_replace);
     "YY"   fprintf(yyout,"%s",upper_replace);
     %%
     
     int main(argc,argv)
     int argc;
     char **argv;
     {
        if(argc < 3){
          printf("Usage %s lower UPPER\n",argv[0]);
          exit(1);
        }
        strcpy(lower_replace,argv[1]);
        strcpy(upper_replace,argv[2]);
        yylex();
        return(0);
     }

すべてのスキャナ関数の名前を変更するには、 コマンドライン上で以下のように実行するだけです。

     replace myscan_ MYSCAN_ < lex.yy.c > myscan.c

これにより、 好きなだけ多くのスキャナを含めることができるようになります。 ほとんど同じことを、 排他的スタート状態と複数のバッファを使って実現することも可能ですが、 その方法は多少複雑になります。

注:いくつかのFlex内部ルーチンは、 将来Flexライブラリ(‘-lfl’)の中に移されるでしょう。 そうなると、 このテクニックは機能しなくなります。 しかし、 この変更が行われる時には、 変更する必要のある関数名を変更する方法を、 Flex自身がサポートするようになるでしょう。2


脚注

[1] 訳注:Flex 2.5では、 Flex起動時に‘-Pprefix’オプションを指定するか、 スキャナ定義ファイルの中に‘%option prefix="prefix"’を指定することによって、 接頭辞‘yy’を別の文字列に変更することができます。

[2] 訳注:Flex 2.5では、 ‘-Pprefix’オプションや‘%option prefix="prefix"’を指定することにより、 関数名を変更することができます。