22

yacc ファイルのユニオンの目的は何ですか? flex ファイルの yylval に直接関連していますか? yylval を使用しない場合は、union を使用する必要はありませんか?

4

2 に答える 2

36

の目的は、unionさまざまな種類のオブジェクトを flex によって発行されたノードに格納できるようにすることです。

よりよく説明するには、たとえば次のようにします。

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

、および型.yの基本的なサポートを提供する場合はint、. これで何ができますか?floatstring

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

さらに、フレックス文法で値を直接使用できます。

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

最後に、OOP 構文ツリーを使用する場合は、union を次のように定義できます。

%union
{
    class ASTNode *node;
}

ASTNode、あらゆる種類の構文ノードの祖先クラスです。

于 2009-12-05T19:45:45.440 に答える
19

%union宣言は の型を変更しますyylval

bisonマニュアルの説明

通常の (再入不可) パーサーでは、トークンのセマンティック値をグローバル変数に格納する必要があります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. */
...
于 2009-12-05T19:42:59.293 に答える