我在 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
}
最佳答案
当 exprPass
在词法分析器(或为 Bison 准备的任何其他东西)中赋值时,s
是否设置为指向词法分析器中包含识别字符串?如果是这样,那么发生的事情是:
- 第一个表达式被识别,
exprPass
被设置为指向它。 - 词法分析器重新使用缓冲区以继续识别字符串。
- 现在第一个
exprPass
指向一个不再包含原始字符串的缓冲区。 - 当解析器有两个表达式时,它们指向同一个缓冲区,因此它们包含相同的字符串。
要解决此问题,您必须在首次识别每个字符串时为其创建一个副本(或以其他方式保留其值),并且在不再需要该字符串时必须释放该副本的内存。根据您的需要,当词法分析器识别并将数字存储在 exprPass
中时,将字符串转换为数字可能会更容易。然后您只有该值的一个副本,而不必处理复制字符串和管理内存分配。
关于c - Bison 堆栈值 ($n) 被覆盖(使用 C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14940310/