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.