将值从 flex 传递给 bison

passing value from flex to bison

我正在尝试在从 flex 发送的 bison 中打印令牌值,但出于某种原因,在某些情况下打印的值是垃圾。

lex 代码:

\".*\" {
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(); }

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++ 代码并且 运行 它工作正常,我不明白为什么会这样,所以有人可以找出其中的错误。

以下是未定义的行为:

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 是局部变量,但您正试图 return 指向它的指针。由于 s3 将在 return 语句执行后立即被破坏,指针将悬空在未分配的内存中,稍后尝试使用它会产生不可预知的后果。

无论如何,序列是不必要的。 Flex 将变量 yyleng 设置为标记的长度,因此您可以简单地使用它来构造您实际需要的字符串:

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