[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