【问题标题】:Flex & Bison Segmenation faultFlex & Bison 分段错误
【发布时间】:2015-05-01 08:35:16
【问题描述】:

我要制作一个编译器,并为此使用 flex 和 bison。 我正在实施布尔比较。但是当野牛进入我的令牌 COMP 时出现错误。

我已经这样声明了:

("==")|(">=")|("<=")|("!=")|(">")|("<")
{
   sscanf(yytext,"%s",yylval.svalcmp); return COMP;
}

在野牛中,我的语法是:

ExpBool :
  Exp COMP Exp { printf("TEST= %s \n",$2); /*comp_exp_temp($2);*/} 
| Exp BOPE Exp
| NEGATION Exp 
;

我的工会:

%union {
  char cval;
  char * sval;
  char * svalt;
  char * svalcmp;
  char svalas;
  char * svalds;
  int signedint;
  int usint;
}

和令牌 decaring :

%token <svalcmp> COMP

Bison 执行第一个 Exp,但是当它读取 COMP 时,我得到一个分段错误。

有人有想法吗?

【问题讨论】:

  • 您需要显示更多代码(尤其是创建 yylval 联合的代码),但很可能您在其中有一个简单的 char *,您永远不会设置指向任何地方有效。
  • 我已添加我的联合代码

标签: c bison flex-lexer


【解决方案1】:

我通常在词法分析器中使用不同的样式,因此无法验证 (...)|(...)... 语法是否正确。但是,您的工会与 yylval 有什么关系? svalcmp 是缓冲区还是指针?如果它是一个缓冲区,您可能应该将 scanf 格式限制为一个长度。如果它只是一个指针,那么您可能已经占用了内存,并且可能会遇到空指针崩溃。

如果您在 GDB 中调用它,请附加回溯,并打印 yylval

【讨论】:

  • 如果是 char *,那么 sscanf 正在写入内存的某个随机位置。有时,它是可写内存(你在其他一些变量上乱涂乱画,你的堆栈,堆等等);其他时候,它可能是非法地址(例如 0)。因此,当它看起来可以工作(即,没有崩溃)时,您已经写入内存并稍后成功访问它(尽管其他东西可能会因此而崩溃)。当你 SEGV 时,那是因为它是一个无效的地址。
  • 如果你能保证大小不超过 3 个字节(两个字节和一个 null),我会将 svalcmp 设为 char[3],你应该可以正常工作。
  • 我已将我的 char * 转换为示例 char 选项卡。现在它工作正常。谢谢:)
猜你喜欢
  • 2013-10-24
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
  • 2011-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多