被覆盖的野牛堆栈值($ n)(使用C)

时间:2013-02-18 16:01:18

标签: c char bison

我在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
}

1 个答案:

答案 0 :(得分:1)

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

  • 识别出第一个表达式,并设置exprPass指向它。
  • 词法分析器重用缓冲区继续识别字符串。
  • 现在第一个exprPass指向一个不再包含原始字符串的缓冲区。
  • 当解析器有两个表达式时,它们指向同一个缓冲区,因此它们包含相同的字符串。

要解决此问题,您必须在首次识别时对每个字符串进行复制(或以其他方式保留其值),并且必须在不再需要该字符串时释放该副本的内存。根据您的需要,当词法分析器识别出该字符串并将该数字存储在exprPass时,可能更容易将字符串转换为数字。然后你只有一个值的副本,而不必处理复制字符串和管理内存分配。