Bison:$$和$1指向相同的内存位置(两个指针类型的联合YYSTYPE)
Bison: $$ and $1 point to the same memory location (union YYSTYPE of two pointer types)
我正在为一个非常简单的解析器构建一个解析器,突然开始获取SEGFAULT。我已经把我的代码精简到了出错的最低限度:
这是我的test.flex文件:
%{
#include "test.tab.h"
#include <iostream>
using namespace std;
%}
%option noyywrap
%%
model { yylval.a = new double(); return IDENTIFIER; }
. { cerr << "Unrecognized token!" << endl; exit(1); }
%%
这是我的测试.y文件:
%{
#include <iostream>
using namespace std;
int yylex();
int yyerror(const char *p) { cerr << "Error" << endl; }
%}
%union YYSTYPE {
double* a;
int* b;
};
%token <a> IDENTIFIER
%type <b> expression
%%
expression : IDENTIFIER { cout << "got here! " << $1 << "|" << $$ << endl; };
%%
int main()
{
yyparse();
cout << "Success!" << endl;
return 0;
}
我们的并集由两个指针组成,a和b。$1和$$的类型不同(分别为a和b(。
在输入"model"上,输出为"gethere!0x372a28|0x372a28"(第二行为"Success!"(,这意味着$1和$$指向相同的内存位置!这当然会导致各种不好的事情发生。
lexer中对yylval.a的赋值是bug显现所必需的。
我使用Bison 2.4.1和Flex 2.5.4,两者都适用于Windows(使用GnuWin32(。我做错什么了吗?这是一个(已知的(错误吗?
编辑:如果我将联盟更改为:
%union YYSTYPE {
int a;
int b;
};
以及的规则
expression : IDENTIFIER { cout << "got here! " << &$1 << "|" << &$$ << endl; };
(并删除lexer中的赋值(描述的结果内存位置不同,这让我相信,如果不使用指针,变量本身的内存位置也不同。然而,如果我使用指针,那么赋值"yylval.a=new double((;"应该只更改$1,并保持$$不变。
这不是Bison中的错误,这就是Bison的工作方式。它使用堆栈来处理中间解析结果,在您的规则中,有一个令牌要从堆栈中移出,另一个要添加,因此要弹出的项和要推入的项显然位于同一内存位置。
因为你在这里做类型强制(?(,我想你在行动中应该有类似的东西
double *a = $1;
$$ = new int((int)(*a));
delete a;
请注意,一旦您写入$$,就无法再读取$1,因为您现在已经占用了$1曾经所在的堆栈插槽。
表达式只有一个组件,因此它的左侧和右侧完全相同。我不知道你为什么会觉得这很奇怪。
我想我可能知道你的困惑在哪里:
expression : IDENTIFIER
这意味着expression
的一个有效形式是IDENTIFIER
。因此,任何是有效IDENTIFIER
的东西也是有效expression
。
- 我有两个类需要在同一 cpp 文件中相互引用,但第一个类无法识别第二个类类型的对象
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 可以将两个相同类型的连续数组视为一个数组吗?
- 如何允许模板参数中的类类型,仅当它有两个基类时
- 测试两个类型列表中的所有组合
- 在类 A 中创建类型为 B 类的向量 - 访问数据 [C++] [成员在两个类中都是私有的]
- 堆栈分配的类类型.为什么两个 ID 实例的地址相同?
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- 如何创建两个具有相同名称和不同返回类型并基于布尔参数运行的函数
- 为什么 Clang 和 GCC 中两个无符号整数之和的结果类型不同
- 在C++中组合两个类型为T的数组
- 如何在不实例化两个c++类型的情况下确定这两个类型
- 这两个类型定义有什么区别?
- 使用共享指针在两个类型模板化类之间进行强制转换
- 交换类型列表中的两个类型
- 具有不同const限定符的两个类型之间的转换
- 带有两个类型参数的模板化函数在与错误检查宏一起使用时无法编译
- 如何在编译时推导出两个类型共有的继承树的根(如果存在)
- 检查两个类型在c++中是否相等
- 两个(类型)值和类型(值)有什么区别