Quel est le but de l'union dans le fichier yacc? Est-il directement lié à yylval dans le fichier flex? Si vous n'utilisez pas yylval, vous n'avez pas besoin d'utiliser union?yylval et union
Répondre
La déclaration %union
modifie le type yylval
.
Le bison
manuel explains:
Dans un analyseur ordinaire (non réentrants), la valeur sémantique du jeton doit être stocké dans la variable globale
yylval
. Lorsque vous utilisez un seul type de données pour les valeurs sémantiques,yylval
a ce type. Ainsi, si le type estint
(par défaut), vous pouvez écrire ceci dansyylex
:... yylval = value; /* Put value onto Bison stack. */ return INT; /* Return the type of the token. */ ...
Lorsque vous utilisez plusieurs types de données, le type de
yylval
est une union fait de la déclaration%union
(voir la section La Collection de types de valeur). Ainsi, lorsque vous stockez la valeur d'un jeton, vous devez utiliser le membre approprié de l'union. Si la déclaration%union
ressemble à ceci:%union { int intval; double val; symrec *tptr; }
alors le code
yylex
pourrait ressembler à ceci:... yylval.intval = value; /* Put value onto Bison stack. */ return INT; /* Return the type of the token. */ ...
Le but du union
est de permettre le stockage différents types d'objets dans les noeuds émis par flex.
Pour expliquer mieux vous pouvez par exemple:
%union
{
int intValue;
float floatValue;
char *stringValue;
}
dans .y
si vous voulez fournir un soutien de base pour int
, float
et string
types. Que pouvez-vous faire avec ça?
Deux choses:
D'abord, vous pouvez définir automatiquement les valeurs de droite lors de la génération de jetons. Pensez à .l
fichier de l'exemple précédent, vous pouvez:
[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;
}
En outre, vous pouvez utiliser la valeur directement dans votre grammaire flex:
nexp: nexp '+' nexp { $<floatValue>$ = $<floatValue>1 + $<floatValue>3 }
Enfin, si vous envisagez d'utiliser une syntaxe POO arbre, vous pouvez définir l'union comme
%union
{
class ASTNode *node;
}
dans lequel ASTNode
est la classe ancêtre de toute sorte de s noeud yntax. Pourquoi définir une union d'un élément?
Pourquoi? Pourquoi ne pas simplement '#define YYSTYPE class ASTNode *' (si la mémoire est bonne). –