Anda di halaman 1dari 16

Flex a la rpida

Jos Ignacio Medina

Octubre, 2008

Este documento se distribuye bajo una licencia Creative Commons bync-sa 2.0. Usted es libre de copiar, distribuir, comunicar y ejecutar pblicamente este documento, y hacer documentos derivados, bajo las siguientes condiciones:

1. Debes reconocer y citar la obra de la forma especicada por el autor o el licenciante. En este caso, debes reconocer que la autora del documento es ma y de los colaboradores, en caso de citarme en algn documento de tu autora. No necesitas mi permiso explcito. 2. No puedes utilizar esta obra para nes comerciales. 3. Si alteras o transformas esta obra, o generas una obra derivada, slo puedes distribuir la obra generada bajo una licencia idntica a sta.

Puedes contactarte conmigo a travs del mail kephalophoros@gmail.com. Si es que dispones de ejemplos como los descritos en este documento, y que quieras compartir con los dems, no dudes en envirmelos. Obviamente, te agregar como colaborador al documento.

ndice general

1. Teora 1.1. Qu es ex? . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2. Qu necesitamos? . . . . . . . . . . . . . . . . . . . . . . . . 1.3. Cmo empezamos a trabajar? . . . . . . . . . . . . . . . . . .

3 3 4 6

2. Prctica 2.1. Simulando un DFA . . . . . . . . . . . . . . . . . . . . . . . .

9 9

2.2. Reconociendo un texto simple . . . . . . . . . . . . . . . . . . 13

Captulo 1 Teora
1.1. Qu es ex?

Flex es una herramienta para generar scanners (reconocedores). Un scanner es un programa que reconoce patrones lxicos en un texto. Flex recibe desde la lnea de comandos una descripcin del scanner a ser implementado desde un archivo especicado por el usuario. La descripcin del scanner est formada por pares de expresiones regulares y cdigo C, llamadas reglas. Flex genera el cdigo C equivalente a la descripcin pedida por el usuario, cdigo que est contenido en el archivo fuente lex.yy.c. Este archivo contiene el cdigo fuente de un autmata nito determinista, capaz de reconocer las expresiones regulares entregadas por el usuario en el archivo de entrada. Despus de compilar el archivo, obtendremos un ejecutable que contendr a nuestro reconocedor. Cuando es ejecutado, el reconocedor analizar su entrada (ya sea un archivo o texto por teclado) en busca de texto que calce con las expresiones regulares denidas en el archivo inicial. Cada vez que el reconocedor encuentre un calce entre un texto ledo y una regla existente, se ejecutar el cdigo en C correspondiente a esa regla. 3

Figura 1.1: Flex se encarga de transformar las especicaciones (reglas y acciones) que nosotros denamos a un cdigo C que representa al analizador.

Lo anteriormente descrito se puede entender mejor observando la Figura 1.1, la cual nos muestra el proceso necesario para obtener el cdigo fuente del analizador. Una vez que tenemos el cdigo fuente del analizador, debemos compilarlo para obtener el ejecutable. Para esto, necesitamos un compilador de C/C++. Una vez que compilemos las fuentes, obtendremos un ejecutable que, dependiendo cmo fue programado desde ex, recibir un archivo de entrada para ser analizado, o simplemente recibir expresiones desde la lnea de comandos, esperando a encontrar calces y ejecutando acciones cuando corresponda. El proceso completo puede entenderse mejor observando la Figura 1.2, en la cual se muestran los pasos a seguir para obtener un ejecutable desde un archivo fuente en ex.

1.2.

Qu necesitamos?

Por lo visto anteriormente, podemos deducir algunas cosas que necesitaremos antes de ponernos a trabajar. Condiciones obvias para trabajar con ex, adems de las ganas y/o la obligacin, seran: 4

Figura 1.2: Pasos necesarios para pasar de un archivo de fuentes en ex a un reconocedor ejecutable.

1. Obviamente, ex instalado en nuestro computador. Los ejemplos del presente documento se procesaron con ex 2.5.34. 2. Un compilador de C/C++. En nuestro caso, usamos gcc, el cual viene includo en casi todas las distribuciones de Linux. La versin utilizada es gcc 4.2.3. 3. Un editor de texto, ojal con resaltado de sintaxis. Como recomendacin pueden usar gedit, emacs, kite, etc. 4. Un sistema operativo en donde correr todo lo anterior. Es ms fcil trabajar sobre Linux, ya que la instalacin de software (y de sus dependencias) es ms ordenada. En nuestro caso, usamos Ubuntu Hardy 8.04, con un kernel 2.6.24-21-generic.

Para empezar a trabajar, primero debemos cumplir con todos los requisitos descritos anteriormente. Una vez que tenemos Ubuntu instalado, podemos instalar todo lo necesario haciendo un 5

$ sudo a p t i t u d e i n s t a l l g cc f l e x lo cual instalar los programas y todas las dependencias necesarias (incluso las recomendadas).

1.3.

Cmo empezamos a trabajar?

Para empezar a trabajar, debemos abrir un editor de texto y empezar a escribir las reglas de nuestro reconocedor. Para esto abrimos gedit, y escribimos lo siguiente: / d e f i n i c i o n e s / %% / r e g l a s / %% / c d i g o de u s u a r i o / En la seccin de deniciones podemos incluir cdigo C para declarar variables, funciones, deniciones de tipos, includes, etc. Tambin podemos darles nombres a expresiones regulares que nosotros denamos (despus veremos como hacer esto). La seccin de reglas est compuesta por dos columnas; una de patrones y otra de acciones. Por cada patrn hay asociada una o ms acciones, en donde patrones son expresiones regulares reconocidas, y acciones son cdigos C denidos por el programador. Si existe una cadena que sea coincidente con ms de un patrn, se escoge la que tenga un mayor nmero de coincidencias. La seccin de cdigo de usuario contiene sentencias creadas por necesidad del programador, por ejemplo, cdigo para la lectura de un chero de texto.

Mtodos, macros y variables Accin o nalidad variable yytext almacena el token actual variable yyleng almacena la longitud de yytext macro ECHO muestra yytext en stdout mtodo yylex() inicia el reconocimiento de lexemas Cuadro 1.1: Mtodos y macros frecuentes usados en ex.

Por mientras, guardemos este archivo con el nombre ejemplo.l. Luego lo llenaremos de reglas y cdigos en el captulo de prctica. Primero, hay algunas cosas que debemos aprender de ex antes de ponernos a escribir cdigo. Flex dispone de mtodos y variables que hacen ms fcil el anlisis de las palabras reconocidas por el autmata. Por ejemplo, yytext contiene un puntero global al ltimo lexema reconocido. As mismo, yyleng contiene la longitud del lexema reconocido. yyin e yyout se encargan de los procesos de entrada y salida, respectivamente (p.e. al trabajar con cheros, yyin se utiliza para el archivo de entrada). La funcin yylex() inicia el proceso de reconocimiento de lexemas, por lo cual debera ser lo primero que ejecutemos una vez que abramos el archivo de entrada. Una tabla de los principales mtodos y macros usados en ex puede verse en el Cuadro 1.1. Con respecto al archivo de entrada de ex, necesitamos saber algunas cosas respecto a las reglas y acciones que podemos utilizar. Como accin, podremos utilizar cualquier cantidad de cdigo C, segn sean nuestras necesidades. El cdigo para las acciones puede utilizar los mtodos y variables mencionadas en el prrafo anterior. En el caso de las reglas, los patrones por los cuales se buscarn las palabras 7

Expresin regular . e* e+ [abc...n] a-e ^e [^abc...n] e$ e{a,b}

Signicado cualquier cosa excepto un salto de lnea \n ninguna o cualquier nmero de e una o cualquier nmero de e a b c ... n (conjuncin) cualquier caracter de {a, b, c, d, e} e debe estar al principio de la lnea cualquier caracter excepto a, b, c ... e aparece al nal de la lnea entre a y b concatenaciones de e

Cuadro 1.2: Un subconjunto de las expresiones regulares disponibles en ex.

estarn denidos por expresiones regulares, algunas de las cuales se describen, junto con su signicado, en el Cuadro 1.2. Algo que siempre debemos recordar es que cuando ms de alguna expresin regular sirva para describir una palabra, ex ele la expresin que tenga el mayor nmero de caracteres coincidentes. Si es que eso no soluciona el problema, ex opta por la regla escrita primero en el archivo fuente. Un listado ms amplio de expresiones regulares reconocidas por ex, y las variables, macros y mtodos que implementa, puede ser encontrado en el manual ocial de la herramienta1 .

Flex, versin 2.5: Un generador de analizadores lxicos rpidos, de Vern Paxson

Captulo 2 Prctica
Ya con un poco de teora encima, podemos empezar a probar con algunos ejemplos. Como dimos en el Captulo 1, la idea es que tengas los programas instalados, y un archivo de texto abierto con las secciones de deniciones, reglas y cdigo de usuario comentadas. Si es que hay algo que no entiendas, o que no te haya quedado claro del Captulo 1, lee detenidamente la documentacin ocial de ex. En todo caso, cada vez que en los ejemplos se ocupen comandos nuevos o algn mtodo no explicado anteriormente, se har una breve explicacin de su uso.

2.1.

Simulando un DFA

En este ejemplo buscaremos reproducir un DFA, es decir, un autmata nito determinista. El DFA a simular es el de la Figura 2.1. La idea es que nuestro programa sea capaz de recibir por la lnea de comandos una palabra, y en caso de que ocurra una condicin de trmino una vez que hayamos terminado 9

Figura 2.1: DFA a simular.

de escribir nuestra palabra (una vez que oprimamos ENTER), el programa nos devuelva la palabra reconocida por el DFA. En caso de no estar sobre una condicin de trmino (estado nal de nuestro autmata), el programa da aviso y termina. As mismo, si es que ingresamos un caracter no reconocido por el autmata, el programa da aviso y termina su ejecucin. El programa en ex que simula al autmata sera: %{ / programa en f l e x para s i m u l a r un DFA / %} %x B C %% <INITIAL>0 <INITIAL>1 <INITIAL>\n

{yymore ( ) ; BEGIN(B) ; } {yymore ( ) ; BEGIN(C) ; } { p r i n t f ( " No e s t s en un e s t a d o f i n a l \n " ) ; 10

<INITIAL >[^01] <B>0 <B>1 <B>\n <B>[^01] <C>0 <C>1 <C>\n <C>[^01]

exit (1);} { p r i n t f ( " S l o c e r o s y unos ! \ n " ) ; exit (1);} {yymore ( ) ; BEGIN(C) ; } {yymore ( ) ; BEGIN(B) ; } { p r i n t f ( " No e s t s en un e s t a d o f i n a l \n " ) ; exit (1);} { p r i n t f ( " S l o c e r o s y unos ! \ n " ) ; exit (1);} {yymore ( ) ; BEGIN( INITIAL ) ; } {yymore ( ) ; BEGIN( INITIAL ) ; } { p r i n t f ( " Palabra r e c o n o c i d a : % \n " , y y t e x t ) ; s exit (1);} { p r i n t f ( " S l o c e r o s y unos ! \ n " ) ; exit (1);}

Ok, ahora copiamos el cdigo a un procesador de textos, y lo guardamos como DFA.l en la carpeta en la que estemos trabajando. Ahora, desde consola, nos movemos a la carpeta de trabajo y ejecutamos $ f l e x DFA. l con lo que deberamos recibir un archivo llamado lex.yy.c. Ahora debemos compilar este archivo, haciendo $ g cc o DFA l e x . yy . c l f l y recibiendo de parte del compilador un ejecutable de nombre DFA. Ahora, slo nos resta probar que realmente funciona nuestro simulador de DFA. En la consola, ejecutamos el simulador escribiendo $ . /DFA

11

y empezamos a escribir palabras. Puedes probar con las siguientes palabras: 01110, 101, 0000001, 001 y 1b0. Observa los mensajes de aprobacin o rechazo de las palabras, e inere los estados por los que pas el autmata hasta que presionaste ENTER: Los resultados son los esperados?. Con el conocimiento que tenemos hasta ahora, hay algunas cosas del cdigo que no quedan totalmente claras, como por ejemplo: Qu quiere decir la lnea %x B C? Es la denicin de las condiciones de arranque, en este caso, B y C. La idea de una condicin de arranque es poder denir reglas que se activen condicionalmente, lo cual es conveniente para nuestro problema ya que deseamos que despus de cada consumo de un caracter pasemos a otro estado, que a su vez tiene otras condiciones para pasar de un estado a otro. Para saber ms sobre las condiciones de arranque consulta el manual ocial de ex. A qu se reere con <INITIAL>? Es el nombre de la primera condicin de arranque por defecto. En el ejemplo, la hemos usado para representar el estado A (el estado inicial del DFA). Para qu sirve yymore()? yymore() le dice al reconocedor que la prxima vez que haga calzar una regla, el token correspondiente debe ser concatenado como prejo al valor actual de yytext().

12

2.2.

Reconociendo un texto simple

Se nos presenta el problema de reconocer un texto simple, con el n de calcular la cantidad de palabras presentes en el texto, y la cantidad de lneas de ste. Tomemos como ejemplo el siguiente texto: Las i n c o l o r a s i d e a s v e r d e s duermen f u r i o s a m e n t e . Pobre de a q u e l i n d i v i d u o que s e a t r e v a a d e s p e r t a r l a s . Primero, abrimos un editor de texto y copiamos el texto de ejemplo en l. Luego, lo grabamos con el nombre ejemplo.txt. Ahora, debemos crear un nuevo documento, y escribir un cdigo parecido a ste: %{ u n s i g n e d c o n t a d o r P a l a b r a s = 0 , c o n t a d o r L i n e a s = 1 ; %} l e t r a [ azAZ ] p a l a b r a { l e t r a }+ e s p a c i o [ ]+ puntuacion [ . , ( ) ! ? : ; ] e o l \n %% { palabra } { espacio } { puntuacion } { eol } . c o n t a d o r P a l a b r a s ++; / nada / / nada / c o n t a d o r L i n e a s ++; { p r i n t f (" % s no e s v l i d o \n " , y y t e x t ) ; p r i n t f ( " S l o l e t r a s y puntuacin . " ) ; exit (1);}

%% 13

main ( argc , argv ) int argc ; c h ar argv ; { i f ( argc > 1) { FILE f i l e ; f i l e = f o p e n ( argv [ 1 ] , " r " ) ; if (! file ) { f p r i n t f ( s t d e r r , " E r r o r en a r c h i v o \n " ) ; exit (1); } yyin = f i l e ; } yylex ( ) ; p r i n t f ( " El a r c h i v o t i e n e : \ n " ) ; p r i n t f (" %d p a l a b r a s \n " , c o n t a d o r P a l a b r a s ) ; p r i n t f (" %d l n e a s \n " , c o n t a d o r L i n e a s ) ; return 0; } Lo guardamos con el nombre textoSimple.l. Luego, siguiendo los pasos del ejemplo anterior, hacemos: $ f l e x textoSimple . l $ g cc o l e e r l e x . yy . c l f l $ . / l e e r ejemplo . txt Con lo que obtenemos como resultado que el texto est compuesto por 15 palabras y 2 lneas. Este ejemplo nos permite observar que pueden generarse reglas en ex de una 14

gran complejidad: con las reglas para expresiones regulares que conocemos podramos reconocer textos mucho ms complejos, como un formulario de registro o una cha mdica. Ya sabemos formar palabras, y bajo reglas similares podemos formar nmeros enteros, decimales, fracciones, RUTs, nombres con nmeros en ellos (por ejemplo, variables en lenguajes de programacin), operaciones matemticas complejas, uso de parntesis, etc. Debemos darnos cuenta de que lo que reconocer nuestro autmata ser estrictamente lo que nosotros le ordenemos que reconozca. Por ejemplo, el texto de ejemplo puede haber estado compuesto por las siguientes lneas a s d f qwerty LOL ROFLMAO cuak ! y seguir siendo perfectamente legal, ya que nuestra denicin de reglas lo permite. En ningn caso estamos analizando si las palabras reconocidas tienen signicado, solamente estamos vericando su legalidad a nivel lxico.

15

Anda mungkin juga menyukai