开发者

yylval and union

开发者 https://www.devze.com 2022-12-13 12:52 出处:网络
What is the purpose of union in the yacc file?Is it directly related to yylval in the fl开发者_运维技巧ex file?If you don\'t use yylval, then you don\'t need to use union?The purpose of the union is t

What is the purpose of union in the yacc file? Is it directly related to yylval in the fl开发者_运维技巧ex file? If you don't use yylval, then you don't need to use union?


The purpose of the union is to allow storing different kind of objects into nodes emitted by flex.

To explain better you can have for example:

%union
{
    int intValue;
    float floatValue;
    char *stringValue;
}

in .y if you want to provide basic support for int, float and string types. What can you do with this?

Two things:

First, you can automatically set right values when generating tokens. Think about .l file of the previous example, you can have:

[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;
}

In addition you can use value directly in your flex grammar:

nexp: nexp '+' nexp { $<floatValue>$ = $<floatValue>1 + $<floatValue>3 }

Finally if you plan to use an OOP syntax tree you can define union as

%union
{
    class ASTNode *node;
}

in which ASTNode is the ancestor class of any kind of syntax node.


The %union declaration modifies the type of yylval.

The bison manual explains:

In an ordinary (nonreentrant) parser, the semantic value of the token must be stored into the global variable yylval. When you are using just one data type for semantic values, yylval has that type. Thus, if the type is int (the default), you might write this in yylex:

...
yylval = value;  /* Put value onto Bison stack. */
return INT;      /* Return the type of the token. */
...

When you are using multiple data types, yylval's type is a union made from the %union declaration (see section The Collection of Value Types). So when you store a token's value, you must use the proper member of the union. If the %union declaration looks like this:

%union {
  int intval;
  double val;
  symrec *tptr;
}

then the code in yylex might look like this:

...
yylval.intval = value; /* Put value onto Bison stack. */
return INT;          /* Return the type of the token. */
...
0

精彩评论

暂无评论...
验证码 换一张
取 消