neu*_*cer 17 parsing yacc bison lexical-analysis
yacc文件中union的目的是什么?它是否与flex文件中的yylval直接相关?如果你不使用yylval,那么你不需要使用union?
Jac*_*ack 27
其目的union
是允许将不同类型的对象存储到flex发出的节点中.
为了更好地解释你可以有例如:
%union
{
int intValue;
float floatValue;
char *stringValue;
}
Run Code Online (Sandbox Code Playgroud)
在.y
如果要提供基本的支持int
,float
和string
类型.你能用这个做什么?
两件事情:
首先,您可以在生成令牌时自动设置正确的值.想想.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;
}
Run Code Online (Sandbox Code Playgroud)
另外,您可以直接在flex语法中使用值:
nexp: nexp '+' nexp { $<floatValue>$ = $<floatValue>1 + $<floatValue>3 }
Run Code Online (Sandbox Code Playgroud)
最后,如果您计划使用OOP语法树,则可以将union定义为
%union
{
class ASTNode *node;
}
Run Code Online (Sandbox Code Playgroud)
其中ASTNode
是任何类型语法节点的祖先类.
Gre*_*con 14
该%union
声明修改的类型yylval
.
该bison
手册介绍:
在普通(非重入)解析器中,令牌的语义值必须存储在全局变量中
yylval
.当您仅使用一种数据类型作为语义值时,yylval
具有该类型.因此,如果类型是int
(默认值),您可以将其写入yylex
:Run Code Online (Sandbox Code Playgroud)... yylval = value; /* Put value onto Bison stack. */ return INT; /* Return the type of the token. */ ...
当您使用多种数据类型时,
yylval
类型是由%union
声明构成的并集(请参阅值类型集合一节).因此,当您存储令牌的值时,您必须使用联合的正确成员.如果%union
声明如下:Run Code Online (Sandbox Code Playgroud)%union { int intval; double val; symrec *tptr; }
然后代码
yylex
可能如下所示:Run Code Online (Sandbox Code Playgroud)... yylval.intval = value; /* Put value onto Bison stack. */ return INT; /* Return the type of the token. */ ...