Как инициализировать значение% union в Bison? - PullRequest
1 голос
/ 11 августа 2009

В Бизоне у меня есть союз

%union
{
   std::string* sval;
}

И я хочу использовать это так

В Lex:

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

Вместо

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

Для предотвращения утечек памяти легко

Однако мне нужен какой-то способ для выделения std :: string для sval.

Как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 11 августа 2009

Вы не можете безопасно помещать типы с конструкторами или деструкторами (такими как std :: string) в объединение, поэтому это не сработает.

Вместо этого вы вообще не можете использовать% union - вместо этого используйте макрос, чтобы напрямую сопоставить YYSTYPE с другим типом:

%{
#define YYSTYPE std::string
%}

тогда yylval будет такого типа (как и все опции $ n в грамматическом коде)

0 голосов
/ 11 августа 2009

Я не полностью понятно, почему вы хотите это сделать, но я понимаю, почему то, что у вас есть, не работает. Это потому что "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.
}

Источник синтаксического анализатора бизонов:

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

Возвращает фиксированный указатель на строку ABCD с без выделения или освобождения в коде Bison вообще (и очень мало даже в основном коде).

...