next up previous contents
Next: 6.4 Integración con ICEeditor Up: 6.3 Integración con el Previous: 6.3.6 Actualización no determinista

6.3.7 Recuperación de información del componente léxico

Una vez que ha sido realizado el análisis léxico de una palabra, el analizador sintáctico generado por ICE debe ser capaz de acceder a al información almacenada en la variable token. Para ello es necesario definir una serie de funciones de acceso a los distintos valores y también realizar algunos cambios en el generador de analizadores de ICE.

Funciones de recuperación de información

Puesto que los analizadores generados por ICE están escritos en código LE-LISP,mientras que el analizador léxico está escrito en C, es necesasrio escribir un conjunto de funciones que permitan acceder a los valores de una estructura C de tipo ice_lex_token desde funciones LE-LISP. Puesto que la manipulación de los campos de una estructura C desde un programa LE-LISP se presenta ciertamente complicada, se ha decidido utilizar una función de acceso para cada uno de los campos de la estructura. Todas estas funciones toman como argumento un puntero a un componente léxico:

Es necesario definir una función que permita obtner la dirección de la variable token. Puesto que esta varible sólo debe ser accedida cuando ha finalizado el análisis léxico de una palabra, o lo que es lo mismo, cuando termina la ejecución de la función yylex, se ha optado por definir una nueva función denominada yygalenalex que se encargará de:

El fichero output.c

En el fichero output.c se genera, entre otras cosas, el código que será localizado en el fichero de salida yacc lang.tab.c. Concretamente, en la función Le_Lisp_ouput_token_translations se genera la macro {ice}:translate que realiza la interpretación del valor devuelto por el analizador léxico a través de yylex. En nuestro caso, en vez de llamar a yylex llamaremos a yygalenalex. Por ahora, para realizar el análisis sintáctico, al analizador le es suficiente con conocer la categoría a la cual pertenece la palabra. En fases más avanzadas, la incorporación del análisis semántico hará necesario el acceso al resto de la información almacenada en la variable token.

Por consiguiente, la definición de la función Le_Lispoutput_token_translation queda como se muestra en el siguiente fragmento de código:

void
Le_Lisp_output_token_translations()
{
  register int i, j;
/*   register short *sp; JF unused */
  if (translations)
    {
      fprintf(ftable,"\n(defextern _get_category (t) fix)");
      fprintf(ftable,
              "\n(dmd {ice}:translate (x)\n
                      `(let ((x (_get_category ,x)))\n
                            (if (le x %d) (vref {ice}:yytranslate x) %d)))\n",
              max_user_token_number, nsyms);
      if (ntokens < 127)  /* play it very safe; check maximum element value.  */
        fprintf(ftable, "\n(defvar {ice}:yytranslate #[     0");
      else
        fprintf(ftable, "\n(defvar {ice}:yytranslate #[     0");
      j = 10;
      for (i = 1; i <= max_user_token_number; i++)
        {
          putc(' ', ftable);
          if (j >= 10)
            {
              putc('\n', ftable);
              j = 1;
            }
          else
            {
              j++;
            }
          fprintf(ftable, "%6d", token_translations[i]);
        }
      fprintf(ftable, "\n])\n");
    }
  else
    {
      fprintf(ftable, "\n(dmd {ice}:translate (x) `(,x))\n");
    } 
}

El fichero ice.ll

Este fichero pertenece a la parte del intérprete de ICE. Se puede decir sin lugar a dudas que su código constituye el núcleo fundamental del intérprete. Entre sus funciones se encuentra la de cargar el código del analizador léxico y realizar las oportunas llamadas a la función yylex. En esta implementación, se sustituirán tales llamadas por invocaciones a la función yygalenalex, definida anteriormente.

Para ello, en la función {ice}:load-scanner, inmediatamente depués de haber cargado el analizador léxico, se debe declarar como externa la función yygalenalex, junto con el resto de las funciones utilizadas en la interacción con el analizador léxico. Esta declaración se realiza mediante defextern.

Las funciones en las que hay que cambiar las llamadas a _yylexgif por llamadas a _yygalenalex son las siguientes:


next up previous contents
Next: 6.4 Integración con ICEeditor Up: 6.3 Integración con el Previous: 6.3.6 Actualización no determinista

Miguel A. Alonso Pardo
Thu Nov 20 16:47:01 CET 1997