2009-12-05 14 views
14

¿Cuál es el propósito de la unión en el archivo yacc? ¿Está directamente relacionado con yylval en el archivo flexible? Si no usa yylval, ¿no necesita usar union?yylval y unión

Respuesta

11

La declaración %union modifica el tipo de yylval.

El bison manual de explains:

En un analizador ordinario (no reentrante), el valor semántico del token deben almacenarse en la variable global yylval. Cuando usa solo un tipo de datos para valores semánticos, yylval tiene ese tipo. Por lo tanto, si el tipo es int (por defecto), puede escribir esto en yylex:

... 
yylval = value; /* Put value onto Bison stack. */ 
return INT;  /* Return the type of the token. */ 
... 

Cuando está utilizando varios tipos de datos, el tipo yylval 's es una unión hecha de la declaración %union (ver sección El Colección de tipos de valor). Por lo tanto, cuando almacena el valor de un token, debe usar el miembro adecuado de la unión. Si la declaración %union se ve así:

%union { 
    int intval; 
    double val; 
    symrec *tptr; 
} 

entonces el código en yylex podría tener este aspecto:

... 
yylval.intval = value; /* Put value onto Bison stack. */ 
return INT;   /* Return the type of the token. */ 
... 
21

El propósito de la union es permitir el almacenamiento de diferentes tipos de objetos en nodos emitidos por flex.

Para explicar mejor que puede tener, por ejemplo:

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

en .y si desea proporcionar soporte básico para int, float y string tipos. ¿Qué puedes hacer con esto?

dos cosas:

En primer lugar, puede configurar automáticamente los valores correctos cuando se genera tokens. Piense en .l archivo del ejemplo anterior, se puede tener:

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

Además se puede usar el valor directamente en su gramática flex:

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

Por último, si tiene previsto utilizar una sintaxis de programación orientada a objetos el árbol se puede definir como la unión

%union 
{ 
    class ASTNode *node; 
} 

en el que ASTNode es la clase ancestro de cualquier tipo de s nodo de yntax

+3

¿Por qué definir una unión de un elemento? ¿Por qué no simplemente '#define YYSTYPE class ASTNode *' (si la memoria sirve). –