1

bison/flex パーサーを再入可能にするための手順に従うのに苦労しています。

問題はレクサーにあるようです。すべてのパーサーは再入可能であるため、yylval を直接割り当てることはできなくなりました。代わりに、Flex のマニュアルに従って、この関数を呼び出す必要があります。

void yyset_lval ( YYSTYPE * yylvalp , yyscan_t scanner );

しかし問題は、YYSTYPE が整数型であることです。これは動的に割り当てられた値ではなく、左辺値ではないため、ポインターを渡すことはできません! 何か不足していますか? そうでない場合は、yylvalue をどのように設定すればよいですか? 非再入可能パーサーでこの問題が発生したことはありません!

更新:わかりました、整数型の問題を乗り越えた可能性があります。入力が設定されていないため、パーサーがクラッシュしたように見えます。入力を読み取る場所をレクサーに伝える方法に関するドキュメントが見つかりません。

フレックスファイル:

%{
#define YYSTYPE Token // Token is a typedef to an integral type
// following two lines added per suggestion from Chris Dodd
#define YYPARSE_PARAM yyscan_t scanner
#define YYLEX_PARAM scanner

%}
%option reentrant
%option bison-bridge

// ...

{D}+{IS}?               {
    *yylval = Tokenint(strtol(yytext,0,10));
     return(CONSTANT); 
}

バイソンファイル:

%{
#define YYSTYPE Token
%define pure-parser
%lex-param {void * scanner}
%parse-param {void * scanner}
%token CONSTANT
// ...

パーサーの次の行でクラッシュが発生します。

*yy_cp = yyg->yy_hold_char;

解析のためにすべてを正しく初期化していない可能性があると思います。マニュアルはこの件に関して非常に混乱しており、多くの場合、型や変数がどこから来たのか、なぜ使用されるのかを説明せずに参照しています。私はこの方法で解析を呼び出しています:

void * scanner;
yylex_init(&scanner);
yyparse(scanner); // Note: was &scanner, this is wrong and will crash!

ソースコードを読んでみると、yylex_init は a を割り当ててstruct yyguts_tゼロに設定しています。クラッシュに達したとき、yy_cp はヌル ポインターです。実際には、全体struct yyguts_tがまだゼロに設定されています。そのため、何かを適切に初期化していないと思われます。その結果、どこから入力を取得すればよいかわかりません。

最終編集:元の質問が回答されたため、この質問をクローズ済みとしてマークし、新しい問題を新しい質問として再度開きます。

4

1 に答える 1

4

通常、再入可能なパーサー/スキャナーを作成するには、ファイル内とファイル内で使用%option bison-bridgeします。これにより、グローバル変数の代わりに引数が作成されます。さらに、次のものが必要です。.l%define api.pure.yyylvalyylex

%{
#define YYPARSE_PARAM yyscan_t scanner
#define YYLEX_PARAM scanner
%}

.yファイルの先頭に追加scannerパラメーターを追加して、パーサーを介してレクサーに渡します。

YYSTYPEである場合(ファイルにまたは宣言intがない場合)、次のように言ってトークン値を設定します%unionYYSTYPE.y.l*yylval = whatever;

于 2012-09-18T01:00:35.160 に答える