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; \
}
%}