1

我在 Bison 中编写了一个解析器,它对表达式的作用如下:

expr: 
   integer{
     exprPass pass;
     sprintf(s, load instructions, $1); //s is a global char buffer
     pass.s= s;
     pass.type = int;
     $$ = pass;
   }
   |
   double{
     exprPass pass;
     sprintf(s, load instructions, $1); //s is a global char buffer
     pass.s= s;
     pass.type = int;
     $$ = pass;
   }
   (etc)

这工作正常,直到我通过类似的东西运行它

comparison: expression LESSTHAN expression

当我打印 $1.s 时,它与 #3.s 相同!

$2 有正确的运算符,没有问题

我知道表达工作正常;使用 printfs 用 2<0 测试它告诉我 pass.s 得到 2,然后是 0。我不知道 $1 是如何以某种方式设置为 $3 ...我必须认为问题出在我的 C 代码中?

我的表达式结构是

typedef exprPass{
   char* s;
   variable_type type;
   //some other data
}
4

1 回答 1

1

何时exprPass在词法分析器中分配(或为 Bison 准备的其他任何东西),s设置为指向词法分析器中包含已识别字符串的缓冲区?如果是这样,那么正在发生的事情是:

  • 第一个表达式被识别,并且 anexprPass被设置为指向它。
  • The lexical analyzer reuses the buffer to continuing recognizing strings.
  • Now the first exprPass is pointing to a buffer that no longer contains the original string.
  • When the parser has both expressions, they are pointing to the same buffer, so they contain the same string.

To fix this, you must make a copy of each string (or otherwise preserve its value) when it is first recognized, and you must release the memory of that copy when the string is no longer needed. Depending on your needs, it may be easier to convert the string to a number when the lexical analyzer recognizes that and to store the number in exprPass. Then you have only a copy of the value and do not have to deal with copying strings and managing memory allocations.

于 2013-02-18T16:21:11.873 回答