[C con Clase] Ayuda con Lex y Yacc
Steven Davidson
srd4121 en njit.edu
Sab Jun 5 08:09:48 CEST 2010
Hola Rafael,
Rafael Enriquez Herrador wrote:
> 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.
>
La regla semántica se aplica en cuanto YACC pueda determinar la regla
sintáctica a aplicar. Por ejemplo,
suma : numero '+' numero { $$ = $1 + $2; }
| suma '+' numero { $$ = $1 + $2; }
;
Digamos que tenemos la siguiente cadena: "5 + 4 + 2". YACC aplicará la
2ª regla, pero antes de poder ejecutar la semántica, tiene que aplicar
la 1ª regla completamente. Por lo tanto, se ejecuta el código de la
primera regla y después el código de la segunda.
En cuanto al problema que presentas, no puedo determinar si el problema
está en la implementación de las funciones concerniendo a la
manipulación de la lista enlazada. Por lo tanto, me queda mirar el
"código" para YACC. No veo nada que hayas hecho que sobresalga de
repente, pero creo que hay una regla que no enviaste correctamente.
Escribiste:
lista_declaracion:
/* No hace nada */ {...}
| tipo_dato IDENTIFICADOR ';' {...}
lista_declaracion {...}
| lista_declaracion COMENTARIO {...}
;
Creo que falta algo en la 3ª regla.
Como quieres que una regla semántica se ejecute antes que o otra, por el
tema de la creación de la lista dinámicamente enlazada, entonces
asegúrate de tener la definición de la regla sintáctica que conduce a la
creación de la lista al principio y las otras posteriormente.
Otra solución es implementar una sola función en cualesquier casos en
los que vayas a agregar un elemento. Por ejemplo, puedes tener una sola
función llamada 'agregar()' que averigüe la forma correcta de tratar la
lista, tanto si está vacía como si no. Obviamente, hay que crear esa
lista, para que sea vacía al principio, antes de poder invocar
'agregar()'. Sugiero crear la lista al comienzo de la interpretación de
tu pseudocódigo. En tu ejemplo, creo que conviene crear la lista al
tratar el terminal 'ALGORITMO'.
Usando Google, vi este ejemplo que usa una lista dinámicamente enlazada
para crear una serie de menúes:
http://luv.asn.au/overheads/lex_yacc/yacc.html#mem_struct
Espero que todo esto te sirva.
Steven
Más información sobre la lista de distribución Cconclase