C Flex&;野牛分异断层

C Flex&;野牛分异断层,c,bison,flex-lexer,C,Bison,Flex Lexer,我想做一个编译器,我用flex和bison来做。 我正在实现布尔比较。但我有一个错误,当野牛进入我的代币公司 我宣布: ("==")|(">=")|("<=")|("!=")|(">")|("<") { sscanf(yytext,"%s",yylval.svalcmp); return COMP; } 我的工会: %union { char cval; char * sval; char * svalt; char * svalcmp; ch

我想做一个编译器,我用flex和bison来做。 我正在实现布尔比较。但我有一个错误,当野牛进入我的代币公司

我宣布:

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

%union {
  char cval;
  char * sval;
  char * svalt;
  char * svalcmp;
  char svalas;
  char * svalds;
  int signedint;
  int usint;
}
和令牌衰减:

%token <svalcmp> COMP
%token COMP
Bison执行第一个Exp,但当它读取COMP时,我得到一个分段错误


有人有主意吗

我通常在lexer中使用不同的样式,因此无法验证(…)|(…)。。。语法正确。然而,你们的工会与耶尔瓦尔有什么联系?svalcmp是缓冲区还是指针?如果它是一个缓冲区,您可能应该将scanf格式约束一个长度。如果它只是一个指针,那么您可能占用了内存,并可能遇到空指针崩溃


如果您在GDB中打开它,附加一个回溯,并打印yylval

,您需要显示更多的代码(特别是创建
yylval
联合的代码),但很可能您在其中有一个普通的
char*
,您从未设置为指向任何有效的地方。如果它是char*,我已经添加了我的联合代码,然后sscanf将写入内存的某个随机位置。有时,它是可写内存(您在其他变量、堆栈、堆等上涂鸦);其他时候,它可能是非法地址(例如0)。因此,当它看起来工作(即,不崩溃)时,您已将其写入内存并在以后成功访问它(尽管其他东西可能会因此崩溃)。当你SEGV时,这是因为它是一个无效的地址。如果你能保证大小不超过3个字节(两个字节和一个null),我会让svalcmp成为一个字符[3],你应该可以正常工作。我已经将我的字符*转换为一个示例字符选项卡。现在工作很好。谢谢:)
%token <svalcmp> COMP