在yacc文件中,联合体的作用是什么?它是否直接与flex文件中的yylval相关?如果您不使用yylval,则不需要使用union吗?
在yacc文件中,联合体的作用是什么?它是否直接与flex文件中的yylval相关?如果您不使用yylval,则不需要使用union吗?
union
的目的是允许将不同类型的对象存储到由flex生成的节点中。
为了更好地解释,您可以举例如下:
%union
{
int intValue;
float floatValue;
char *stringValue;
}
如果你希望在 .y
文件中为 int
、float
和 string
类型提供基本支持,可以这样做:
有两件事情:
首先,你可以在生成 token 时自动设置正确的值。考虑上一个示例中的 .l
文件,可以这样写:
[a-zA-Z][a-zA-Z0-9]* {
yylval.stringValue = strdup(yytext);
return IDENTIFIER;
}
[0-9]+ {
yylval.intValue = atoi(yytext);
return INTEGER;
}
[0-9]*\.[0-9]+"f"? {
yylval.floatValue = new atof(yytext);
return FLOAT;
}
此外,您可以直接在flex语法中使用value:
nexp: nexp '+' nexp { $<floatValue>$ = $<floatValue>1 + $<floatValue>3 }
最后,如果您计划使用面向对象编程的语法树,您可以将union定义为:
%union
{
class ASTNode *node;
}
ASTNode
是任何语法节点的祖先类。
%union
声明修改了yylval
的类型。
bison
手册解释:
在普通(非可重入)解析器中,标记的语义值必须存储到全局变量
yylval
中。当您为语义值使用一个数据类型时,yylval
就具有该类型。因此,如果类型是int
(默认值),则可以在yylex
中编写如下内容:
...
yylval = value; /* Put value onto Bison stack. */
return INT; /* Return the type of the token. */
...
当您使用多个数据类型时,yylval
的类型是由 %union
声明创建的联合体(请参见值类型的集合部分)。因此,当您存储标记的值时,必须使用联合体的正确成员。如果 %union
声明如下:
%union {
int intval;
double val;
symrec *tptr;
}
那么在yylex
中的代码可能会像这样:
...
yylval.intval = value; /* Put value onto Bison stack. */
return INT; /* Return the type of the token. */
...
#define YYSTYPE class ASTNode *
(如果我没记错的话)? - Chris Lutz