yacc ファイルのユニオンの目的は何ですか? flex ファイルの yylval に直接関連していますか? yylval を使用しない場合は、union を使用する必要はありませんか?
2 に答える
の目的は、union
さまざまな種類のオブジェクトを flex によって発行されたノードに格納できるようにすることです。
よりよく説明するには、たとえば次のようにします。
%union
{
int intValue;
float floatValue;
char *stringValue;
}
、および型.y
の基本的なサポートを提供する場合はint
、. これで何ができますか?float
string
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. */ ...