2009-12-05 4 views
14

yaccファイルの結合の目的は何ですか?それはflexファイルのyylvalに直接関係していますか? yylvalを使用しない場合は、unionを使用する必要はありませんか?yylvalとunion

答えて

11

%unionの宣言は、yylvalのタイプを変更します。

bison手動explains:通常(非リエントラント)パーサーで

、トークンの意味値は、グローバル変数yylvalに格納されなければなりません。意味値に1つのデータ型のみを使用する場合は、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の目的は、放出されたノードにオブジェクトの異なる種類を格納できるようにすることですフレックスで.y

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

をあなたはintfloatstring種類の基本的なサポートを提供する場合:あなたは、たとえば持つことができ、より良い説明すること

。これで何ができますか?

2つのこと:

まずトークンを生成するとき、あなたは自動的に正しい値を設定することができます。前の例の程度.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; 
} 

あなたフレックス文法に値を直接使用することができます加えて:あなたはOOPの構文を使用する場合は最後に

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

ツリーあなたはASTNodeは、Sのいずれかの種類の上位クラスである

%union 
{ 
    class ASTNode *node; 
} 

として組合を定義することができますyntaxノード。

+3

なぜ1つの要素の和集合を定義するのですか?なぜ '#define YYSTYPE class ASTNode *'(メモリが提供されているのか)だけではありません。 –