tutorial example compilador parsing yacc bison lexical-analysis

parsing - example - yacc python



yylval y unión (2)

¿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?


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

El manual del bison explica :

En un analizador ordinario (no original), el valor semántico del token debe 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 (el valor predeterminado), puede escribir esto en yylex :

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

Cuando está utilizando múltiples tipos de datos, el tipo de yylval es una unión hecha a partir de la declaración %union (consulte la sección Colección de tipos de valores). Por lo tanto, cuando almacena el valor de un token, debe usar el miembro adecuado de la unión. Si la declaración %union tiene este aspecto:

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

entonces el código en yylex podría verse así:

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


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

Para explicar mejor, puede tener, por ejemplo:

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

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

Dos cosas:

Primero, puede establecer automáticamente los valores correctos al generar tokens. Piensa en el archivo .l del ejemplo anterior, puedes 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, puede usar el valor directamente en su gramática flexible :

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

Finalmente, si planea usar un árbol de sintaxis de OOP, puede definir la unión como

%union { class ASTNode *node; }

en el que ASTNode es la clase antecesora de cualquier tipo de nodo de sintaxis.