次のページ 前のページ 目次へ

5. C++ での構文解析器の作成

Lex と YACC は C++ が登場する以前からありますが、C++ で構文解析器を作 成することも可能です。Flex には C++ の 字句解析器を生成するオプション もありますが、YACC の方にそれを直接扱う方法がないので、ここでは使用し ません。

筆者が C++ の構文解析器を作る際に好んで使う方法は、Lex に普通の C ファ イルの字句解析器を出力させて、YACC に C++ の構文解析器を生成させるやり 方です。アプリケーションをリンクした時に、この方法だと問題がある場合 があります。C++ では明示的に extern "C" 宣言しない限り、デ フォルトでは C の関数を見つけられないからです。

これを回避するためには、YACC で以下のような C ヘッダを作ってください。

extern "C"
{
        int yyparse(void);
        int yylex(void);  
        int yywrap()
        {
                return 1;
        }

}

yydebug を宣言もしくは、変更したい場合はここで以下のように行ってくださ い。

extern int yydebug;

main()
{
        yydebug=1;
        yyparse();
}

これは、C++ の '定義は一度' 規則のために必要で、yydebug の多重定義を防 ぎます。

加えて、C++ では型チェックがより厳しいので、YYSTYPE の #define を Lex ファイルに追記しないとだめかもしれません。

コンパイルするには、以下のようにしてください。

lex bindconfig2.l
yacc --verbose --debug -d bindconfig2.y -o bindconfig2.cc
cc -c lex.yy.c -o lex.yy.o
c++ lex.yy.o bindconfig2.cc -o bindconfig2 

-o 指定があるので、y.tab.h は bindconfig2.cc.h という名前になっている ことにも留意してください。

まとめ - 字句解析器のコンパイルは、わざわざ C++ でやろうとしないで C でやること。構文解析器は C++ で作り、C 関数を呼び出したい時は extern "C" 文でコンパイラに宣言すること。


次のページ 前のページ 目次へ