1

バイソンには組合があります

%union
{
   std::string* sval;
}

そしてこんな風に使いたい

レックスでは:

*(yylval->sval) = "ABCD";

それよりも

yylval->sval = new std::string("ABCD");

簡単にメモリリークを防ぐには

ただし、最初に std::string を sval に割り当てる方法が必要です。

どうやってやるの?

4

2 に答える 2

2

コンストラクタまたはデストラクタ (std::string など) を含む型を共用体に安全に配置することはできないため、これは機能しません。

代わりにできることは、 %union をまったく使用しないことです。代わりに、マクロを使用して YYSTYPE を他の型に直接マップします。

%{
#define YYSTYPE std::string
%}

yylval がその型になります (文法コードのすべての $n オプションと同様)

于 2009-08-10T23:13:04.523 に答える
0

なぜこれをやりたいのかは完全にはわかりませんが、あなたが持っているものが機能しない理由はわかります. ではなく である"ABCD"からです。const char *std::string

最初のセクションでは、Yacc の制御外で C の内容を定義できることを Yacc で知っています (また、Bison には、上位互換性の主張と2.1.1"%{ ... %}"のドキュメントに基づいて、同様の機能があるようです) 。なぜ入れないのですか:

std::string *strABCD = new std::string("ABCD");

そのセクションで、次を使用します。

yylval->sval = strABCD;

後でその文字列へのポインターが必要になったときはいつですか?

それは、あなたが望むもの(私が思うに)を達成するための最も簡単な方法だと私には思えます。

Bison パーサー内の割り当てが解放されないことを心配している場合 (解放する必要があります)、私のアドバイスは、そこで解放しないことです。呼び出す前に文字列を設定し、yyparse()戻り後に解放することができます。

アップデート:

Bisonパーサー内でその固定値を割り当て/解放しないようにする方法は次のとおりです。プログラムの期間中存続するグローバルとして設定します。

メインコード:

std::string *strABCD = new std::string ("ABCD");

int main(...) {
    // Do some stuff.
    : : :
    yyparse();
    : : :
    // Do some other stuff.
}

Bison パーサーのソース:

%{
    extern std::string *strABCD;
%}
: : :
yylval->sval = strABCD;

これは、Bison コードでの割り当てや解放をまったく行わずに、ABCD 文字列への固定ポインタを返します(メイン コードでも貴重なものはほとんどありません)。

于 2009-08-10T22:58:41.293 に答える