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

输入字符串长度超9时AST创建触发段错误求助

问题分析与解决

问题原因

  1. Flex正则规则语法错误:你的范围匹配规则写错了——把匹配左方括号的\[误写成了\^(匹配脱字符^)。原规则\[^?([^\\\]]|\\.)*\]实际会匹配以^开头、后跟可选?、最后以]结尾的字符串,完全不符合你要解析的[...]格式范围表达式。
  2. 错误匹配引发内存越界:由于规则不匹配预期输入,Flex要么触发其他规则处理(逻辑不符),要么在错误匹配逻辑下导致yytext指向的缓冲区出现越界访问,最终在创建AST时触发段错误。
  3. 补充:你用strdup(yytext)的操作是正确的(避免Flex内部缓冲区覆盖问题),但规则错误导致yytext内容异常,才引发后续问题。

解决步骤

1. 修正Flex正则规则

将规则中的\^改为\[,正确匹配左方括号,同时保留可选的脱字符(用于否定范围,如[^abc])。修正后的规则:

\[\^?([^\\\]]|\\.)*\] { yylval.value = strdup(yytext); return TOKEN_RANGE; }

规则拆解:

  • \[:匹配左方括号[
  • \^?:可选匹配脱字符^(支持[^123]这类否定范围)
  • ([^\\\]]|\\.)*:匹配任意非]且非转义开头的字符,或转义后的任意字符(支持\[这类转义括号)
  • \]:匹配右方括号]

2. 添加未匹配输入的错误处理

在Flex规则末尾添加默认规则,捕获未匹配的字符,避免Flex默认输出未匹配内容导致的意外行为:

. { fprintf(stderr, "Unexpected character: %c\n", yytext[0]); exit(1); }

3. 强化AST创建的鲁棒性

在CreateAstLeaf中添加长度检查,避免空字符串或异常长度输入导致的问题:

ast_t *CreateAstLeaf(node_t type, char *val) {
  ast_t *new_leaf = malloc(sizeof(ast_t));
  if (!new_leaf) {
    perror("Out of space.");
    exit(1);
  }

  if (val == NULL || strlen(val) == 0) {
    fprintf(stderr, "Invalid empty range string.\n");
    exit(1);
  }

  new_leaf->type = type;
  size_t val_len = strlen(val);
  new_leaf->value = calloc(val_len + 1, sizeof(char));
  strcpy(new_leaf->value, val);

  return new_leaf;
}

4. 调试匹配过程

可以在Flex规则中添加打印语句,确认匹配内容是否符合预期:

\[\^?([^\\\]]|\\.)*\] { 
    printf("Matched range token: %s\n", yytext);
    yylval.value = strdup(yytext); 
    return TOKEN_RANGE; 
}

验证测试

修正后重新编译Flex和Bison代码,测试长范围输入:

./parse -r
/[1234567890abcdef]/

此时应该正常输出Accepted!,不再触发段错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:53:16