gpt4 book ai didi

c - 在非终端 Bison 规则之间传递多个值

转载 作者:行者123 更新时间:2023-12-04 02:10:29 25 4
gpt4 key购买 nike

当我将规则与我的词法分析器(用 Flex 编写)匹配时,我试图传递多个值。

{pattern_to_match}           {
yylval.type_val.str=strdup(yytext);
yylval.type_val.int=1;
return TOKEN;
}

这是词法分析器部分
%union {
struct{
char * str;
int int;
}str_int;

%token <str_int> TOKEN

TOKEN {
printf("%s\n",$1.str_int.str);
printf("%s\n",$1.str);
}

在这里我们可以看到 Bison 结构。如教程中所示,我已将两个字符串写入 printf 中,但没有任何效果(对于字符串和整数)。我做错了什么?

最佳答案

您的 %union指令看起来......好吧,就您所展示的内容而言,“几乎可以”,但是缺少右括号。我不能说你省略的部分,但是 int int是一个语法错误,所以我必须假设这也不是什么。

大括号中的代码(flex 和 bison 部分)与 union 中显示的片段不匹配。

这是一些正确的语法(为了讨论目的,我添加了更多名称,以及其他一些使输出可编译的项目 gcc -O -Wall -c ):

%{
#include <stdio.h>
extern int yylex(void);
extern int yyerror(const char *);
%}

%union {
struct named_for_discussion_below {
char *pair_sval;
int pair_ival;
} pair;
int single_ival;
}

%token <pair> TOKEN
%token <single_ival> INTEGER

%%

prog: exprlist;

exprlist: exprlist expr
| /*empty*/
;

expr : TOKEN { printf("got: %s %d\n", $1.pair_sval, $1.pair_ival); }
| INTEGER { printf("got: %d\n", $1); }
;

请注意,由于两个 %token 中提供的类型指令,野牛假定 $1struct named_for_discussion_below 的一个实例,包含 pair_svalpair_ival , 当 token 为 TOKEN ,但那 $1只是一个简单的 single_ival token 为 INTEGER 时的值.访问 .pair_sval 时必须选择结构成员( .pair_ivalpair )值,但您必须省略单词 pair .访问时 single_ival你省略了这个词 single_ival也;因为没有 .field子名称,在 $1 之后没有其他显示.

扩展讨论

至少如果您了解生成的解析器如何工作的基础知识,在此注意解析堆栈的每个元素是一个 union 可能会有所帮助。类型。 (嗯,是在使用 %union 之后,否则就是普通的 int 。)
%union指令提供此类型的内容。它的内部名称是 union YYSTYPE ,它有一个 typedef-alias 拼写为 YYSTYPE ,这是您(或 flex)在为每个标记设置辅助值时应该使用的。每次调用 yylex()必须返回一个普通的 int value,它是 token 号(0 表示 EOF,1 到 255 表示普通 char,以及从 256 或以上开始的 token 值)。 (Byacc 使用 #define 从 257 开始,而现代野牛使用 enum 并从 258 开始。)每个调用也设置 yylval以及 yylval 中的值与 token 一起被推送(移动)到其解析堆栈上。 (bison 和 byacc 都使用两个并行堆栈,一个用于解析器状态,一个用于值,但这是您不需要关心的实现细节。除了“Bob Corbett 编写了两者的第一个版本”之外,我不知道为什么它们都是在这里以同样的方式工作。)

当 bison(或 byacc)发出代码时,它使用分配的或假定的类型,来自 %token , %type或角括号提供的名称,根据需要添加 union 元素名称。例如,假设 yacc 值堆栈被命名为 S (这不仅仅是假设),并假设 $1实际上是 S[1] , $2正在 S[2] , 等等。没有 %union指令和无显式类型, $n直接翻译成 S[n] .当您介绍 %union ,不过,它转换为 S[n].field ,其中 field name 来自隐含或提供的类型。

因此,在上面,当处理 INTEGER只产生一个 single_ival , bison/byacc 生成您需要的内容,而无需您进行额外的工作。但是,在处理 TOKEN 时产生 pair , S[1].pair不足以选择 struct 的一个元素.添加 .pair_sval选择 char * struct 的元素.

结构类型的名称, struct named_for_discussion_below , 永远不会出现在任何自动生成的代码中。如果你想将结构类型的副本或指向它的实例的指针传递给某个例程——例如, alter(&$1) , 当 $1扩展为 S[1].pair — 您将需要使用结构类型的名称。如果您从不这样做,则可以完全省略名称。

关于c - 在非终端 Bison 规则之间传递多个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18551307/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com