Sim*_*cia 2 c struct parameter-passing bison flex-lexer
当我将规则与我的词法分析器(用Flex编写)匹配时,我试图传递多个值.
{pattern_to_match} {
yylval.type_val.str=strdup(yytext);
yylval.type_val.int=1;
return TOKEN;
}
Run Code Online (Sandbox Code Playgroud)
这是词法分析器的一部分
%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);
}
Run Code Online (Sandbox Code Playgroud)
在这里我们可以看到野牛结构.我已经将两个字符串写入printf中,如教程中所示,但没有一个(字符串和int)都有效.我做错了什么?
你的%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); }
;
Run Code Online (Sandbox Code Playgroud)
请注意,由于两个%token指令中提供的类型,bison假定它$1是令牌的实例struct named_for_discussion_below,包含pair_sval和pair_ival,当令牌是TOKEN,但这$1只是single_ival令牌时的一个简单值INTEGER.访问该值时必须选择结构成员(.pair_sval和.pair_ival)pair,但必须省略该单词pair.访问时single_ival你也省略了这个词single_ival; 由于没有.field子名,之后不会出现任何其他内容$1.
至少如果你知道生成的解析器如何工作的基础知识,这可能会有所帮助,这里要注意解析堆栈的每个元素都是一个union类型.(好吧,它是在使用之后%union,否则它只是一个普通的int.)
该%union指令提供此类型的内容.它的内部名称是union YYSTYPE,它有一个typedef-alias拼写YYSTYPE,这是你(或flex)在为每个标记设置辅助值时应该使用的.每次调用yylex()必须返回一个普通int值,即标记号(对于EOF为0,对于普通值为1到255,对于char标记从256或256以上开始的标记值).(Byacc使用#defines从257开始,而现代bison使用a enum并从258开始.)每个调用也设置yylval并且值in yylval被推送(移位)到其解析堆栈以及令牌.(bison和byacc都使用两个并行堆栈,一个用于解析器状态,一个用于值,但这是一个你不需要关心的实现细节.除了"Bob Corbett编写了两者的第一个版本"之外我不知道为什么他们俩这里的工作方式相同.)
当野牛(或byacc)发射码时,它使用所分配的或假定的类型,从%token,%type或尖括号提供的名称,根据需要添加一个联合元素名称.例如,假设yacc值栈被命名S(它不仅仅是假设),并且假设$1实际上是S[1],$2正在S[2]等等.没有%union指令而没有显式类型,$n只需直接转换为S[n].当你介绍%union,但是,将其转换为S[n].field,其中field名字来自于暗示或提供的类型.
因此,在上面,当处理INTEGER只生产a single_ival,bison/byacc的产生你需要的东西而你不需要额外的工作.但是,当处理a TOKEN产生a时pair,S[1].pair不足以选择一个元素struct.添加.pair_sval选择的char *元素struct.
结构类型的名称struct named_for_discussion_below永远不会出现在任何自动生成的代码中.如果要将结构类型的副本或指向其实例的指针传递给某个例程,例如alter(&$1),当$1扩展为S[1].pair- 时,您需要使用结构类型的名称.如果你从不这样做,你可以完全省略名称.
| 归档时间: |
|
| 查看次数: |
2001 次 |
| 最近记录: |