3

lex/yacc から 2 つの別個の解析関数を生成したいと考えています。通常、yacc は関数 yyparse() を提供します。これは、何らかの構文解析を行う必要があるときに呼び出すことができますが、それぞれが異なるレクサーと文法に関連付けられたいくつかの異なる yyparse が必要です。man ページでは -p (プレフィックス) フラグが提案されているようですが、これはうまくいきませんでした。yylval が適切に再ラベル付けされていないことを示す gcc からのエラーを受け取りました (つまり、いくつかの異なるトークンが定義されていないと主張しています)。これらの個別の関数を生成するための一般的な手順を知っている人はいますか?

ありがとう

4

3 に答える 3

2

私は以前に同じ問題を抱えていて、次のヘッダーファイルを書くことになりました:

#ifndef RENAME_FLEX_H
#define RENAME_FLEX_H

#define yy_create_buffer scan__create_buffer
#define yy_delete_buffer scan__delete_buffer
#define yy_init_buffer scan_init_buffer
#define yy_load_buffer_state scan_load_buffer_state
#define yy_switch_to_buffer scan_switch_to_buffer
#define yyin scan_in
#define yyleng scan_leng
#define yylex scan_lex
#define yyout scan_out
#define yyrestart scan_restart
#define yytext scan_text
#define yy_flex_debug scab_flex_debug
#define yywrap scan_wrap
#define yyrealloc scan_realloc
#define yyfree scan_free
#define yy_flush_buffer scan_flush_buffer
#define yypush_buffer_state scan_push_buffer_state
#define yypop_buffer_state scan_pop_buffer_state
#define yy_scan_buffer scan_scan_buffer
#define yy_scan_string scan_scan_string
#define yy_scan_bytes scan_scan_bytes
#define yyget_in scan_get_in
#define yyget_out scan_get_out
#define yyget_leng scan_get_leng
#define yyset_text scan_set_text
#define yyset_in scan_set_in
#define yyset_out scan_set_out
#define yyget_debug scan_get_debug
#define yyset_debug scan_set_debug
#define yylex_destroy scan_lex_destroy
#define yyalloc scan_alloc
#define yyget_text scan_get_text

#endif

に含める.lので、私の.cファイルから、-prefixed ではなく、2 番目のスキャナーに -prefixed シンボルを使用できscan_ますyy

于 2010-03-20T06:18:04.683 に答える
1

yylex()同じバッファの途中で解析コンテキストを変更したくないと仮定して、パーサーを交換する周囲のコード内の関数ポインターはどうですか。

関数ポインターは、プレフィックス オプションを使用してパーサーを含めるか、実行時に DSO から読み込まれたパーサーから設定できます。

これには、AST を処理するコードが、それを生成するために使用されたパーサー/レクサーの組み合わせを認識できないという利点があります。

于 2010-03-19T22:24:04.860 に答える
1

flex/bison を使用している場合は、「再入可能」オプションを使用できます。これにより、同じ (または異なる) スキャナーの複数のインスタンスを持つことができます。このオプションは、最近の flex バージョンに含まれています。私見ですが、同じプログラム内に複数のスキャナー/パーサーを配置するのがよりクリーンな方法です。この記事では、この問題について詳しく説明します。

別の方法は、静的スキャナーの代わりにフレックスの機能を使用して C++ クラスを生成することですが、これにより、C プログラマーはいくつかのラッパー関数を作成する必要があります。

よろしく

于 2010-03-19T22:24:54.947 に答える