从弯曲到野牛的价值

passing value from flex to bison

本文关键字:弯曲      更新时间:2023-10-16

我试图在flex发送的野牛中打印令牌值,但由于某些原因,该值在某些情况下是垃圾。

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($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 代码并运行它的工作正常,我没有得到为什么会发生的,所以有人可以找到错误。

以下是未定义的行为:

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;