yacc ファイルのユニオンの目的は何ですか? flex ファイルの yylval に直接関連していますか? yylval を使用しない場合は、union を使用する必要はありませんか?
2 に答える
の目的は、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、あらゆる種類の構文ノードの祖先クラスです。
%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. */ ...