Bison/Flex 声明混乱...我应该在哪里包含/声明什么?

发布于 2024-12-07 20:22:39 字数 783 浏览 0 评论 0原文

我正在使用 Bison 和 Flex 来制作一对可重入的扫描器/解析器,但无法理解要包含和声明所有内容的位置。

首先,我使用的是可重入 Flex,因此我需要通过声明 %parse-param {yyscan_t Scanner}yyscan_t 扫描仪类型首先传递给 Bison,然后使 Bison通过声明 %lex-param {yyscan_t Scanner} 将其传递给 Flex。但 yyscan_t 并未由 Bison 声明,因此我必须在 Bison 文件中包含 Flex 生成的扫描仪头文件(我将其命名为 Scanner.flex.h)。但由于我的 Flex 文件包含我的 Bison 标头,并且我的 Bison 标头现在包含 Flex 标头,因此我得到了循环包含,这会以不可预测的方式搞乱内容!

假设我想在 Bison 文件中添加 %locations 和 Flex 文件中的 %bison-locations 进行位置跟踪。现在我需要更改 yyerror 和 yylex 的声明(似乎我必须再次定义 yylex,即使它是在 Flex 生成的标头中定义的,但我不能包含它,还记得吗?)我的 Bison 文件中的函数以包含 YYLTYPE 指针。但现在怎么办?似乎默认的 YYLTYPE 声明是在插入序言之后放置的,因此我无法在 yyerror 和 yylex 的声明中使用此默认 YYLTYPE。

我意识到这些问题有很多解决方法......但是你应该如何正确地做到这一点呢?我完全忘记了这件事,这让我的头脑一片混乱......

I'm using Bison and Flex to make a reentrant scanner/parser pair but can't wrap my head around where everything is to be included and declared.

First of all, I'm using reentrant Flex so I need to pass the yyscan_t scanner type first to Bison by declaring %parse-param {yyscan_t scanner} and then make Bison pass this to Flex by declaring %lex-param {yyscan_t scanner}. But yyscan_t is not declared by Bison so I must include the Flex generated scanner header file (which I named scanner.flex.h) in my Bison file. But since my Flex file includes my Bison header, and my Bison header now includes the Flex header, I get circular includes which messes up stuff in unpredictable ways!

And let's say I want to add in location tracking with %locations in my Bison file and %bison-locationsin my Flex file. Now I need to change the declaration of my yyerror and my yylex (it seems I have to define yylex AGAIN even though it's defined in the Flex generated header but I cannot include that, remember?) functions in my Bison file to include the YYLTYPE pointer. But what now? It seems that the default YYLTYPE declaration is placed AFTER the prologue is inserted and thus I cannot use this default YYLTYPE in the declaration of my yyerror and my yylex.

I realize that there are a lot of workarounds to these problems... but how are you supposed to do it properly? It totally escapes me and this just leaves my head a mess...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南笙 2024-12-14 20:22:39

在野牛文件的顶部,您需要转发声明这些值。您可以在包含 flex 和 bison 文件之前在公共标头或代码文件中执行此操作。 yyscan_t 只是 void * 的 typedef,因此我将参数声明为 void 指针以使其正常工作。

CommonHeader.h

int yylex (union YYSTYPE * yyval_param, struct YYLTYPE * yylloc_param, void * yyscanner);
int yyerror(struct YYLTYPE * yylloc_param, void *scanner, const char *s);

yyerror 的示例

int yyerror(struct YYLTYPE * yylloc_param, void *scanner, const char *s)
{
    printf("*** Lexical Error %s %d.%d-%d.%d\n", s, 
         yylloc_param->first_line, yylloc_param->first_column, 
         yylloc_param->last_line, yylloc_param->last_column);
}

In the top of your bison file you need to forward declare these values. You can do this in a common header or in the code file before you include the flex and bison files. yyscan_t is just a typedef of a void * so I declared the parameters as void pointers to get it to work.

CommonHeader.h

int yylex (union YYSTYPE * yyval_param, struct YYLTYPE * yylloc_param, void * yyscanner);
int yyerror(struct YYLTYPE * yylloc_param, void *scanner, const char *s);

Example of yyerror

int yyerror(struct YYLTYPE * yylloc_param, void *scanner, const char *s)
{
    printf("*** Lexical Error %s %d.%d-%d.%d\n", s, 
         yylloc_param->first_line, yylloc_param->first_column, 
         yylloc_param->last_line, yylloc_param->last_column);
}
暮色兮凉城 2024-12-14 20:22:39

在寻找其他东西时遇到了这个。

答案是 Bison 在 %union 规范之后发出 YYLTYPE 的内部声明。因此,将函数原型和其他内容放在 %union 之后的序言部分中可以避免自己声明 YYLTYPE 的问题;这完全没问题,Bison 允许有多个序言部分:

%{

/* Prologue 1 */

%}

%this

%that

%union {}

%{

/* Prologue 2, YYLTYPE declared */

%}

%%

blah:  talk | blah talk

%%

Came across this while looking for something else.

The answer is that Bison emits the internal declaration for YYLTYPE after the %union spec. Hence, putting function prototypes and other stuff in a prologue section after the %union avoids the problem of declaring YYLTYPE yourself; this is quite OK, Bison allows more than one prologue section:

%{

/* Prologue 1 */

%}

%this

%that

%union {}

%{

/* Prologue 2, YYLTYPE declared */

%}

%%

blah:  talk | blah talk

%%
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文