如何在`bison / yacc`中重新定义`YYSTYPE`?

问题描述 投票:0回答:2

我定义了一个用户类来容纳所有对象。但是yacc将创建一个头文件,yylval的类型必须为YYSTYPE。如果我不使用%union,它将作为一个整数保存。但是,如果我使用%union,它将合并。并且联合是丑陋的-它不能容纳一个类或shared_ptr(可以,但不是一个好主意),它只希望我使用指针。

我只想使YYSTYPE具有作为用户类类型的类型。我该怎么办?

yacc
2个回答
0
投票

如您所见,由lexyacc制作的源文件需要由yacc制作的头文件。

标题很短,所以我们可以在其中寻找一些解决方案。

定义yylval的类型的部分是这个:

/* Value type.  */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif


extern YYSTYPE yylval;

因此我们可以在包含YYSTYPE的头文件之前定义yacc,如下所示:

#include "your-header-file-that-define-the-class.h"
#define YYSTYPE your-class-type
#include "the-header-file-that-made-by-yacc.h"

0
投票

请勿使用YYSTYPE

使用野牛-这实际上是您实际使用的yacc实现-定义语义值类型的正确方法是

%define api.value.type { MyType }

如果需要包含一个或多个头文件以使声明有效,请将其放在%code requires块中:

%code requires {
   #include "MyType.h"
}

这些指令的设置被复制到bison生成的头文件中,因此其他文件只需要包含生成的头文件。

警告:请注意,除非您使用bison的C ++接口,否则语义值类型必须是可复制的,这将消除大多数标准C ++库类型。不遵守此规则将产生未定义的行为,在尝试解析足够复杂的输入之前,可能无法检测到该行为。换句话说,使用简单输入进行的测试可能不会发现该错误。

© www.soinside.com 2019 - 2024. All rights reserved.