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

Bison如何正确使用字符串返回值 解决返回字符串包含多余字符问题

Bison字符串返回值使用及多余字符问题解决方案

核心问题根因

你遇到的字符串包含多余字符、解析错误的问题,本质是以下3个底层错误导致:

  • 直接引用Flex的yytext缓冲区:yytext是Flex内部的复用缓冲区,每次识别新token时内容会被覆盖,直接将yytext指针赋值给语义值会导致后续token解析时原有内容被篡改,出现随机字符、多余符号。
  • token规则附带多余空白符:你定义的WORD、MULTIWORD等规则末尾均添加了{WHITE_SPACE}*,会导致识别到的token本身就包含末尾的空格,甚至可能因为规则优先级问题误将后续符号(如})包含到token内容中。
  • 非法内存释放操作:未经过malloc的yytext指针直接调用free会触发内存访问错误,进一步导致内容异常。

正确使用方式及修复步骤

1. 改造Flex词法规则,复制token内容到独立内存

所有返回字符串类型的token,都需要将yytext的内容复制到新申请的堆内存中,使用Flex内置的yyleng变量获取当前token的实际长度,示例如下:

// WORD 类型token处理示例
{WORD}  { 
    yylval.string = malloc(yyleng + 1);
    strncpy(yylval.string, yytext, yyleng);
    yylval.string[yyleng] = '\0'; // 手动补字符串结束符
    return WORD;
}

// 带前缀的ATWORD处理示例(跳过第一个@字符)
{ATWORD} {
    yylval.string = malloc(yyleng); // 跳过1个前缀字符,总长度为 yyleng-1 + 1个结束符 = yyleng
    strncpy(yylval.string, yytext + 1, yyleng - 1);
    yylval.string[yyleng - 1] = '\0';
    return ATWORD;
}

HWORD、UNIT、MULTIWORD等所有返回字符串类型的token都按照上述逻辑修改。

2. 移除规则末尾的多余空白符匹配

你已经单独配置了[ \t]规则忽略空白符,无需在每个token规则末尾添加{WHITE_SPACE}*,直接删除所有token规则末尾的{WHITE_SPACE}*即可,避免token包含多余空格。

3. 修正Bison规则中的字符串操作

  • 单值返回场景:第一条timer规则直接写$$ = $2即可,只要$2是你独立申请的字符串内存,就能正常返回amount的值,无需额外处理。
  • 多字符串拼接场景:按需申请内存,使用snprintf避免溢出,示例如下:
| TILDE WORD amount { 
    printf("Timer: %s Amount:%s\n",$2, $3 );
    // 申请内存长度= $2长度 + $3长度 + 1个空格 + 1个结束符
    $$ = malloc(strlen($2) + strlen($3) + 2);
    snprintf($$, strlen($2) + strlen($3) + 2, "%s %s", $2, $3);
    free($2);
    free($3);
}

所有字符串使用完成后,再调用free释放内存即可,不会出现非法释放问题。

内容的提问来源于stack exchange,提问作者Seth Harlaar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 14:36:04