1

式に対して次のように動作するパーサーを Bison で作成しました。

expr: 
   integer{
     exprPass pass;
     sprintf(s, load instructions, $1); //s is a global char buffer
     pass.s= s;
     pass.type = int;
     $$ = pass;
   }
   |
   double{
     exprPass pass;
     sprintf(s, load instructions, $1); //s is a global char buffer
     pass.s= s;
     pass.type = int;
     $$ = pass;
   }
   (etc)

これは、次のようなものを実行するまで正常に機能します

comparison: expression LESSTHAN expression

$1.s を印刷すると #3.s と同じです!

$2 には正しい演算子があり、問題はありません

式が正常に機能していることはわかっています。printfs を使用して 2<0 でテストすると、pass.s が 2 になり、次に 0 になることがわかります。$1 がどうにかして $3 に設定されているかわかりません... 問題は私の C コードにあると考えなければなりませんか?

私の式の構造体は

typedef exprPass{
   char* s;
   variable_type type;
   //some other data
}
4

1 に答える 1

1

exprPassが字句アナライザー (または Bison 用に準備するもの) で割り当てられた場合s、認識された文字列を含む字句アナライザーのバッファーを指すように設定されますか? もしそうなら、何が起こっているのですか:

  • 最初の式が認識され、exprPassそれを指すように an が設定されます。
  • 字句解析器は、文字列の認識を継続するためにバッファを再利用します。
  • 1 つ目exprPassは、元の文字列が含まれていないバッファーを指しています。
  • パーサーに両方の式がある場合、それらは同じバッファーを指しているため、同じ文字列が含まれています。

これを修正するには、最初に認識されたときに各文字列のコピーを作成する (またはその値を保存する) 必要があり、文字列が不要になったときにそのコピーのメモリを解放する必要があります。必要に応じて、字句解析器がそれを認識したときに文字列を数値に変換し、その数値を に格納する方が簡単な場合がありますexprPass。そうすれば、値のコピーだけが得られ、文字列のコピーやメモリ割り当ての管理に対処する必要がなくなります。

于 2013-02-18T16:21:11.873 に答える