[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