передача значения от гибкого к зубру

Я пытаюсь напечатать значение токена в бизоне, отправленном с flex, но по какой-то причине напечатанное значение является мусором в некоторых случаях.

лекс код:

\".*\" {
std::string* s1 = new std::string(yytext);
std::string s2 = *s1;
std::string s3 = s2.substr(1,s2.size() - 2);
yylval.s = &s3;

return VARIABLE;
}

код бизона:

    %union{
std::string *s;
};

%type <s> expr

expr : VARIABLE { caps($1); }

void caps(std::string *str){
std::string str1 = *str;

for(std::string::size_type i=0;i<str1.length();i++)
std::cout << str1[i];
}

Если я ввожу строку длиной менее 15 символов, она выводит нормально, но если длина выходит за ее пределы, выводится мусор.

Если я изолирую код C ++ и запускаю его нормально, я не понимаю, почему это происходит, поэтому кто-то может найти в нем ошибку.

0

Решение

Следующее является неопределенным поведением:

std::string* s1 = new std::string(yytext);
std::string s2 = *s1;
std::string s3 = s2.substr(1,s2.size() - 2);
yylval.s = &s3;
return VARIABLE;

s3 является локальной переменной, но вы пытаетесь вернуть указатель на нее. поскольку s3 будет разрушен, как только return оператор выполняется, указатель будет оставлен в незанятой памяти, и попытка использовать его позже будет иметь непредсказуемые последствия.

В любом случае последовательность не нужна. Flex устанавливает переменную yyleng на длину токена, так что вы можете просто использовать это для создания строки, которую вы действительно хотите:

yylval.s = new std::string(yytext + 1, yyleng - 2);
return VARIABLE;
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]