2

Bisonのエラー処理に問題があります。私は次の文法を持っています(私は関連する部分だけを切り取っています)。FlexはトークンをBisonに送信し、文字列「ConfigParam」が解析されると終端記号「KW_CONFIGPARAM」を返します。IDENTは、C++文字列オブジェクトへのポインタです。

statementlist   : statement ';'               { $$ = new string("statementlist"); }
                | statementlist statement ';' { $$ = new string("statementlist"); }
;
statement       : KW_CONFIGPARAM IDENT        { $$ = new string("statement"); /* use $2, IDENT is used in main program */ }
;

IDENTのような文字列に次のデストラクタを指定しています。

%destructor {printf( "行%dでフリー:%s \ n"、@ $。first_line、$$-> c_str()); delete($$); }

今、私は次の入力を持っています。最初の行は有効ですが、2番目の行は無効です(識別子がありません):

ConfigParam p;
ConfigParam;

出力:

In input 2:12 - 2:12 : syntax error
free at line 2: p
free at line 1: statementlist

2行目のエラーのため、Bisonは文句を言い、構文エラーを返し、解析スタック上のすべてのオブジェクトのデストラクタを呼び出します。最初の行の識別子「p」のデストラクタが呼び出される理由がわかりません。これは最初の行に属し、正常に解析されました。問題は、pがメインプログラムで使用されており、Bisonによって削除されるべきではないということです。

(無効な)ステートメントとして選択した場合、任意の文字列( "foo")pはBisonによって削除されません。

ConfigParam p;
foo;

In input 2:1 - 2:3 : syntax error
free at line 1: statementlist
free at line 2: foo

なぜこれが機能するのですか?

4

2 に答える 2

1

@rici:どうもありがとう、あなたは私を正しい方向に向けてくれます。私は書いた

%token <str>    STRING    IDENT       NUMBER
                KW_CONFIGPARAM

もちろん、正しいのは...

%token <str>    STRING    IDENT       NUMBER
%token          KW_CONFIGPARAM

うーん!

@rici: あなたは私の一日を作りました!!!

于 2013-01-27T00:46:13.780 に答える
1

ファイルを詳しく見ずに正確な問題を特定するのは簡単ではありませんが、そうではないことは確かです。

最初の行は正常に解析されたので、スタックからポップする必要があります

エラーの時点でのスタックは次のようになります。

statementlist KW_CONFIGPARAM

statementlistbison によって報告されているように、最初の行の削減によって作成された場所。

statement_list の値を指定していないようです。抜粋がリテラルの場合、次のように書かれたかのようにコンパイルされます。

statementlist   : statement ';'                 {$0 = $1;}

に対応する値が何statementであったかはわかりませんが、string が含まれていることは確かに考えられます"p"$0それは、中に何を設定したかによって異なります{ /* do some stuff, create a new ConfigParam object */ }

(正しい答えにいくらか近いことが明らかになったので、コメントから移動しました。) 私の他の考えはこれです: おそらく、すべての端末と非端末に、そのデストラクタをトリガーするタイプを持たせました。また、レクサーがyylval返されたときに変更しない場合もありますKW_CONFIGPARMyylvalその場合、bison パーサーはそれが無関係であることを認識できないため、残りの部分yylval( へのポインター"p") を使用します。

于 2013-01-26T17:47:43.533 に答える