Yaccファイルでの結合の目的は何ですか?フレックスファイルのyylvalに直接関係していますか? yylvalを使用しない場合は、unionを使用する必要はありませんか?
union
の目的は、flexによって発行されたノードにさまざまな種類のオブジェクトを格納できるようにすることです。
よりよく説明するために、あなたは例えば持つことができます:
%union
{
int intValue;
float floatValue;
char *stringValue;
}
int
、float
、およびstring
タイプの基本的なサポートを提供する場合は.y
で。これで何ができますか?
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;
}
さらに、flex grammar:で直接値を使用できます。
nexp: nexp '+' nexp { $<floatValue>$ = $<floatValue>1 + $<floatValue>3 }
最後に、OOP構文ツリーを使用する場合は、ユニオンを次のように定義できます。
%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. */ ...