バイソンには組合があります
%union
{
std::string* sval;
}
そしてこんな風に使いたい
レックスでは:
*(yylval->sval) = "ABCD";
それよりも
yylval->sval = new std::string("ABCD");
簡単にメモリリークを防ぐには
ただし、最初に std::string を sval に割り当てる方法が必要です。
どうやってやるの?
バイソンには組合があります
%union
{
std::string* sval;
}
そしてこんな風に使いたい
レックスでは:
*(yylval->sval) = "ABCD";
それよりも
yylval->sval = new std::string("ABCD");
簡単にメモリリークを防ぐには
ただし、最初に std::string を sval に割り当てる方法が必要です。
どうやってやるの?
コンストラクタまたはデストラクタ (std::string など) を含む型を共用体に安全に配置することはできないため、これは機能しません。
代わりにできることは、 %union をまったく使用しないことです。代わりに、マクロを使用して YYSTYPE を他の型に直接マップします。
%{
#define YYSTYPE std::string
%}
yylval がその型になります (文法コードのすべての $n オプションと同様)
なぜこれをやりたいのかは完全にはわかりませんが、あなたが持っているものが機能しない理由はわかります. ではなく である"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 文字列への固定ポインタを返します(メイン コードでも貴重なものはほとんどありません)。