2009-12-05 495 views
14

yacc文件中union的用途是什麼?它是否與flex文件中的yylval直接相關?如果你不使用yylval,那麼你不需要使用union?yylval和union

回答

11

%union聲明修改yylval的類型。

bison手冊explains

在普通的(不可重入)分析器,令牌的語義值必須被存儲到全局變量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. */ 
... 
21

union的目的是允許存儲不同類型的對象到發射節點通過flex。

更好地說明你可以有例如:

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

,如果你想爲intfloatstring類型提供了基本的支持。你能用這個做什麼?

兩件事情:

首先,你可以生成令牌時自動設置正確的價值觀。想想.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 } 

最後,如果你打算使用OOP語法樹可以定義爲工會

%union 
{ 
    class ASTNode *node; 
} 

其中ASTNode是父類中的任何一種的S的yntax節點。

+3

爲什麼要定義一個元素的聯合?爲什麼不只是'#define YYSTYPE class ASTNode *'(如果內存服務)。 –