yylval 有可能是一个结构体而不是一个联合吗?



在Bison上,yylval可能是一个结构而不是一个联合?我知道我可以将yylval定义为与%union{}的并集,但有没有办法将yylal定义为struct?返回用于示例和访问的标识符的行和字符串这些信息是关于一些格拉玛规则对野牛的作用。

是的,您可以将#define YYSTYPE设置为您想要的任何类型,而不是使用%union。然而,这样做很少有用1——如果您想要源位置信息,最好将%position%union结合使用。

%union声明中使用structs也是可能的(也是常见的(。这使得某些规则可以很容易地(有效地(返回多个值。


1 主要问题是,如果使用%type指定使用一个结构字段,在同一操作中使用其他字段会很痛苦。您需要手动完成所有操作,因此失去了bison的联合类型检查的好处

如果您想保留令牌的位置信息(行号和列号(,可以使用Bison的位置工具,该工具将每个令牌和非终端的位置对象与语义值分开。在动作中,将符号的位置称为@n

如果bison发现您引用了规则中的任何位置,它就会自动创建和维护位置堆栈。

默认情况下,位置数据类型为:

typedef struct YYLTYPE {
int first_line;
int first_column;
int last_line;
int last_column;
} YYLTYPE;

令牌的位置信息必须由lexer设置。如果使用默认的API,则它存储在全局变量yylloc中。解析器将使用从产品的第一个项目开始到最后一个项目结束的范围来创建非终端的位置信息。(对于空产品,将生成一个零长度的位置对象,以先行标记的起始位置开始和结束。(

如果需要,可以覆盖这两个默认值。有关详细信息,请参阅Bison手册。

如果要求使用%option yylineno,Flex将跟踪行号,但它不跟踪列位置,这有点烦人。此外,yylloc需要起始行号和结束行号;弹性动作中的yylineno将是令牌末尾的行号。最常见的情况是,您将使用YY_USER_ACTION宏来保持yylloc的值;一个示例实现(取自这个答案,如果你使用这个代码,你应该阅读它(是:

%option yylineno
%{
#define YY_USER_ACTION                                       
yylloc.first_line = yylloc.last_line;                      
yylloc.first_column = yylloc.last_column;                  
if (yylloc.first_line == yylineno)                         
yylloc.last_column += yyleng;                           
else {                                                     
int col;                                                
for (col = 1; yytext[yyleng - col] != 'n'; ++col) {}   
yylloc.last_column = col;                               
yylloc.last_line = yylineno;                            
}
%}

相关内容

最新更新