[C con Clase] Ayuda con Lex y Yacc

Rafael Enriquez Herrador rafenher07 en gmail.com
Sab Mayo 29 21:25:06 CEST 2010


Hola a todo el mundo,

Tengo que hacer un traductor de pseudocodigo (inventado por mi) a 
lenguaje C para un trabajo de la facultad. Tengo terminado el Lexer y la 
gramatica del Parser (Yacc) con la mayoría de las funciones que se 
utilizarán para traducir el pseudocódigo a C. El problema es que quiero 
crear una lista enlazada donde se almacenen todas las variables 
declaradas y su tipo (entero, real o cadena de caracteres), pero al 
insertar los elementos en la lista desde la regla de Yacc, sólo inserta 
una variable y el resto se pierden. Creo que puede deberse a la forma 
que tiene Yacc de evaluar las reglas para encontrar los "tokens" y a las 
recursiones que utiliza que hace que el puntero que apunta al comienzo 
de la lista se pierda.

Necesito ayuda urgente. He trabajado bastante el pseudocodigo, el lex y 
el yacc, pero no consigo avanzar y tengo que entregar la práctica cuanto 
antes. Agradecería mucho cualquier tipo de ayuda que pudiesen darme.

Para cualquiera que lo necesite, puedo enviar el pseudocódigo, aunque es 
bastante largo y engorroso, por lo que no me atrevo a ponerlo todavía 
por aquí.

Aquí les explico un poco cual es el problema que tengo:

- Para definir las variables que se utilizarán en el algoritmo existe 
una clausula "clausula_variables" que aparecerá de la siguiente forma:

ALGORITMO IDENTIFICADOR
clausula_variables
INICIO
lista_instrucciones
FINALGORITMO

Donde ALGORITMO, IDENTIFICADOR, INICIO y FINALGORITMO son símbolos 
Terminales de la gramática ("tokens" reconocidos por Lex).
El símbolo no terminal "clausula_variables" se define como:

clausula_variables:    /* No hace nada*/    {
                                                                      $$ 
= (char*) malloc((strlen("/* No hay variables declaradas 
*/\n")+1)*sizeof(char));
                                                                      
sprintf($$, "/* No hay variables declaradas */\n");
                                                                     }
                              |    VARIABLES
                                   lista_declaracion
                                   FINVARIABLES        {
                                                                      $$ 
= (char*) malloc((strlen($2)+1)*sizeof(char));
                                                                      
sprintf($$, "%s", $2);
                                                                     }
                             ;

Por otro lado "lista_declaracion" se define como:

lista_declaracion:    /* No hace nada */             {
                                                                      
         $$ = (char*) malloc((strlen(" ")+1)*sizeof(char));
                                                                      
         sprintf($$, " ");
                                                                         
    }

                         |        tipo_dato IDENTIFICADOR    ';'        {
                                                                        
                       /* Insertar la nueva variable en la lista de 
identificadores */
                                                                      
                         printf("\nDeclaracion de variable: '%s%s'\n", 
$1, $2);
                                                                      
                         if(buscarId($2, listaIds) == NOT_DEFINED)
                                                                      
                             {    insertarId($2, 
definirTipoVariable($1), &listaIds); printf("\nVariable insertada\n"); }
                                                                      
                         else
                                                                         
                          printf("\nVariable no insertada\n");
                                                                         
                     }
                                 lista_declaracion                    
             {
                                                                      
                         printf("\nEntrando a 'lista_declaracion':'2'");
                                                                      
                         $$ = (char*) 
malloc((strlen($1)+strlen($2)+strlen($5)+strlen("\n;")+1)*sizeof(char));
                                                                      
                         sprintf($$, "%s%s;\n%s", $1, $2, $5);
                                                                         
                     }
                         |       lista_declaracion COMENTARIO       {
                                                                      
                         $$ = (char*) 
malloc((strlen("/**/\n")+strlen($1)+strlen($2)+1)*sizeof(char));
                                                                      
                         sprintf($$, "%s\n/*%s*/", $1+2, $2);
                                                                         
                     }
                         ;

Como se puede observar, se llama a varias funciones "buscarId", 
"definirTipoVariables", "buscarIds", etc. que hacen uso de una lista 
enlazada "listaIds" que está declarada como una variable global en la 
zona de declaraciones de Yacc entre los símbolos "%{" y "%}". La 
estructura de la lista esta definida en un archivo de cabecera 
"symbol.h" que está incluido en el fichero del Yacc.

Muchas gracias por todo. Y un saludo.

-- 
------------------------------------------------
Rafael Enríquez Herrador - rafenher07 en gmail.com
------------------------------------------------

------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20100529/0e035ef5/attachment.html>


Más información sobre la lista de distribución Cconclase