You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Lex+Yacc解析逻辑表达式加括号时出现值覆盖问题求助

错误1:lex文件多字符运算符识别错误

你当前lex文件中匹配到<=>/=>这类多字符运算符时,直接return *yytext只会返回运算符的第一个字符,比如<=>会被当做'<'返回,完全匹配不到你yacc中定义的<=>/=>规则。

修正方案:

给多字符运算符单独定义token,修改lex文件:

letters [a-zA-Z]
identifier {letters}+
separator [\(\)]    

%%
{identifier} {
    yylval.s = strdup(yytext);
    return IDENTIFIER; }
"<=>" { return EQV; }
"=>" { return IMPLY; }
"|" { return '|'; }
"&" { return '&'; }
"!" { return '!'; }
{separator} { return *yytext; }
[\n] { return '\n'; }
%%

同时在yacc文件开头声明新增的token,调整优先级定义:

%token IDENTIFIER EQV IMPLY
%left EQV
%left IMPLY
%left '|' 
%left '&'
%right '!'
%left '(' ')'

后续规则里把'<=>'改成EQV,'=>'改成IMPLY即可。


错误2:yacc动作块使用局部std::string的临时指针

你所有规则中构造完字符串后直接用$$ = (char *)s3.c_str()赋值,s3是动作块内的局部std::string变量,动作块执行完成后s3就会被销毁,c_str()返回的指针就变成野指针,后续访问该指针时指向的内存可能被后续构造的字符串复用,就是你遇到的“后面的表达式覆盖前面的表达式”的根因。


错误3:IDENTIFIER规则未给$$赋值

你匹配原子表达式IDENTIFIER的规则中,只构造了临时变量,完全没有给$$赋值,会导致后续依赖该原子值的规则拿到的是随机值。


统一修正方案(yacc规则部分)

所有字符串赋值都用strdup把内容复制到堆内存,避免野指针,同时释放不需要的内存避免泄漏:

expr : IDENTIFIER  {  
        $$ = strdup($1);
        free($1);
    }
     | expr EQV expr   {
        string s1($1);
        string s2($3);
        string s3 = "(" + s1 +")<=>(" + s2 +")";
        $$ = strdup(s3.c_str());
        free($1); free($3);
     }
     | expr IMPLY expr   {
        string s1($1);
        string s2($3);
        string s3 = "(" + s1 +")=>(" + s2 +")";
        $$ = strdup(s3.c_str());
        free($1); free($3);
     }
     | expr '|' expr    {
        string s1($1);
        string s2($3);
        string s3 = "(" + s1 +")|(" + s2 +")";
        $$ = strdup(s3.c_str());
        free($1); free($3);
     }
     | expr '&' expr    {
        string s1($1);
        string s2($3);
        string s3 = "(" + s1 +")&(" + s2 +")";
        $$ = strdup(s3.c_str());
        free($1); free($3);
     }
     | '!' expr {      
        string s1($2);
        string s2 = "!" + s1;
        $$ = strdup(s2.c_str());
        free($2);
     }
     | '(' expr ')'         {  $$ = $2; }
     ;

内容的提问来源于stack exchange,提问作者No Reveal Name

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 13:27:02