Цель union
состоит в том, чтобы позволить хранить различные типы объектов в узлах, испускаемых flex.
Чтобы объяснить лучше, вы можете иметь, например:
%union
{
int intValue;
float floatValue;
char *stringValue;
}
in .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;
}
Кроме того, вы можете использовать значение непосредственно в вашей гибкой грамматике :
nexp: nexp '+' nexp { $<floatValue>$ = $<floatValue>1 + $<floatValue>3 }
Наконец, если вы планируете использовать синтаксическое дерево ООП, вы можете определить объединение как
%union
{
class ASTNode *node;
}
, в котором ASTNode
является классом предка любого синтаксического узла.