next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Análisis de la Línea Sup: Expresiones Regulares en Flex Ant: Manejo de directivas include Err: Si hallas una errata ...

Análisis Léxico desde una Cadena: yy_scan_string

El objetivo de este ejercicio es mostrar como realizar un análisis léxico de los argumentos pasados en la línea de comandos. Para ello flex provee la función yy_scan_string(const char * str). Esta rutina crea un nuevo buffer de entrada y devuelve el correspondiente manejador YY_BUFFER_STATE asociado con la cadena str. Esta cadena debe estar terminada por un carácter \0. Podemos liberar la memoria asociada con dicho buffer utilizando yy_delete_buffer(BUFFER). La siguiente llamada a yylex() realizará el análisis léxico de la cadena str.

$ cat scan_str.l
%%
[0-9]+     printf("num\n");
[a-zA-Z]+  printf("Id\n");
%%
main(int argc, char ** argv) {
int i;
 
  for(i=1;i<argc;i++) {
    yy_scan_string(argv[i]);
    yylex();
    yy_delete_buffer(YY_CURRENT_BUFFER);
  }
}
 
int yywrap() { return 1; }
$ flex scan_str.l ; gcc lex.yy.c ; a.out Hello World! 1234
Id
Id
!num
Alternativamente, la función main() podría haber sido escrita asi:
main(int argc, char ** argv) {
int i;
YY_BUFFER_STATE p;

  for(i=1;i<argc;i++) {
    p = yy_scan_string(argv[i]);
    yylex();
    yy_delete_buffer(p);
  }
}
La función yy_scan_bytes(const char * bytes, int len) hace lo mismo que yy_scan_string pero en vez de una cadena terminada en el carácter nulo, se usa la longitud len. Ambas funciones yy_scan_string(const char * str) y yy_scan_bytes(const char * bytes, int len) hacen una copia de la cadena pasada como argumento.

Estas dos funciones crean una copia de la cadena original. Es mejor que sea asi, ya que yylex() modifica los contenidos del buffer de trabajo. Si queremos evitar la copia, podemos usar

yy_scan_buffer(char *base, yy_size_t size),

la cual trabaja directamente con el buffer que comienza en base, de tamaño size bytes, los últimos dos de los cuáles deben ser YY_END_OF_BUFFER_CHAR (ASCII NUL). Estos dos últimos bytes no son ``escaneados''. El área de rastreo va desde base[0] a base[size-2], inclusive. Si nos olvidamos de hacerlo de este modo y no establecemos los dos bytes finales, la función yy_scan_buffer() devuelve un puntero nulo y no llega a crear el nuevo buffer de entrada. El tipo yy_size_t es un tipo entero. Como cabe esperar, size se refiere al tamaño del buffer.


next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Análisis de la Línea Sup: Expresiones Regulares en Flex Ant: Manejo de directivas include Err: Si hallas una errata ...
Casiano Rodríguez León
2012-05-22