Parsing 它';它可能是一个结构而不是一个联合体?

Parsing 它';它可能是一个结构而不是一个联合体?,parsing,bison,Parsing,Bison,在野牛身上,它可能是一个结构而不是一个联盟?我知道我可以用%union{}将yylval定义为union,但是有没有办法将yylval定义为struct?返回example和access的标识符的行和字符串 这些信息是关于一些格拉玛规则对野牛的行为。是的,您可以将YYSTYPE定义为您想要的任何类型,而不是使用%union。但是,执行so1很少有用——如果您想要源位置信息,最好将%position与%union结合使用 在%union声明中使用结构也是可能的(也是常见的)。这使得某些规则很容易(

在野牛身上,它可能是一个结构而不是一个联盟?我知道我可以用
%union{}
将yylval定义为union,但是有没有办法将yylval定义为struct?返回example和access的标识符的行和字符串 这些信息是关于一些格拉玛规则对野牛的行为。

是的,您可以将YYSTYPE定义为您想要的任何类型,而不是使用
%union
。但是,执行so1很少有用——如果您想要源位置信息,最好将
%position
%union
结合使用

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



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

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

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

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

typedef struct YYLTYPE {
  int first_line;
  int first_column;
  int last_line;
  int last_column;
} YYLTYPE;
令牌的位置信息必须由lexer设置。如果您使用的是默认API,它将存储在全局变量
yylloc
中。解析器将使用从产品的第一项开始到最后一项结束的范围,为非终端创建位置信息。(对于空产品,将生成一个零长度位置对象,以先行标记的开始位置开始和结束。)

如有必要,可以覆盖这两个默认值。有关详细信息,请参阅

如果要求Flex使用
%选项yylineno
,它将跟踪行号,但它不跟踪列位置,这有点烦人。此外,
yylloc
需要起始行号和结束行号<代码>yylineno在flex操作中,将是令牌末尾的行号。通常,您将使用
YY_USER_ACTION
宏来维护
yylloc
的值;示例实现(摘自,如果使用此代码,您应该阅读该示例)如下:


我想在yylval中保存yytext和token integer,例如
#define YYSTYPE struct{int-token;char*literal},可能吗?@linrongbin:当然可以。但不要使用
#定义YYSTYPE
;那肯定会给你带来麻烦。您需要确保声明在任何需要的地方都是可见的,这意味着它们应该在bison生成的头中。要实现这一点,请将
struct
声明(
struct MyToken{…}
)放入bison定义中的
code requires
块中,然后使用
%define api.value.type{struct MyToken}
,如中所述。如果你需要更详细的答案,问一个新问题。
%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;                            \
  }
%}