LEXyacc
LEXyacc
LEXyacc
En este apartado y en el siguiente se describe una herramienta particular, llamada Lex, que ha sido ampliamente usada para especificar analizadores lxicos para una variedad de lenguajes. Se har referencia a la herramienta como el compilador Lex, y a su especificaci n de entrada como el len !a"e Lex. !a discusi n de una herramienta existente nos permitir mostrar como la especificaci n de patrones usando expresiones regulares puede estar combinada con acciones, como por ejemplo, crear entradas en una tabla de s"mbolos, expandir macros, o incluso generar documentaci n automticamente. El programa !ex est dise#ado para ser utilizado junto con el programa #acc, que como se ver en el cap"tulo $% es un generador de analizadores sintcticos. !ex suele ser usado seg&n la siguiente figura'
(rimero, se prepara una especificaci n de un analizador lxico creando un programa contenido, por ejemplo en el fichero prog.l, en lenguaje !ex. Entonces, prog.l se pasa a travs del compilador !ex para producir un programa en ), que por defecto se denomina lex.yy.c en el sistema operativo *+$,. -ste consiste en una representaci n tabular de un diagrama de transici n construido a partir de las expresiones regulares de prog.l, junto con una rutina estndar
que usa la tabla de reconocimiento de lexemas. !as acciones asociadas con expresiones regulares en prog.l son trozos de c digo ), y son transcritas directamente a lex.yy.c. .inalmente, lex.yy.c se pasa a travs del compilador ) para producir un programa objeto, que por defecto se llama a.out, el cual es el analizador lxico que transforma una entrada en una secuencia de to/ens. *n programa !ex consta de tres secciones' $Declaracione%& '' $Re la% de (rad!cci)n& '' $Procedimien(o% a!xiliare%& !a %ecci)n de declaracione% incluye declaraciones de variables, constantes y definiciones regulares. !as definiciones regulares son sentencias usadas como componentes de las expresiones regulares que aparecen en las reglas. !as re la% de (rad!cci)n de un programa !ex son sentencias de la forma' p0 1acci n 02 p3 1acci n 32 ... ... pn 1acci n n2 4onde cada pi es una expresi n regular y cada acci ni es un fragmento de programa, describiendo qu acci n debe realizar el analizador lxico cuando el patr n pi se corresponde con un lexema. En !ex, las acciones estn escritas en ). !a tercera secci n contiene cualesquiera procedimientos auxiliares que sean requeridos por las acciones. 5lternativamente, estos procedimientos pueden ser compilados separadamente y montados junto con el analizador lxico. *n analizador lxico creado por !ex funciona en concierto con un analizador sintctico de la siguiente manera. )uando es activado por el analizador sintctico, el analizador lxico comienza leyendo de su entrada un carcter a la vez, hasta que encuentre el prefijo ms largo de la entrada que ha correspondido con una de las expresiones regulares pi. Entonces, ejecuta acci ni, que t"picamente devolver el control al par%er. (ero, si no lo hace,
entonces el analizador lxico procede a buscar ms lexemas, hasta que una acci n contenga una sentencia re(!rn o se lea el fichero completo. !a b&squeda repetida de lexemas hasta una devoluci n expl"cita del control permite que el analizador lxico procese los espacios en blanco y comentarios convenientemente. El analizador lxico devuelve un entero, que representa el (o*en, al analizador sintctico. (ara pasar un valor de atributo con informaci n sobre el lexema, se puede usar una variable global llamada y ylval. Esto se hace cuando se use #acc como generador del analizador sintctico. !os analizadores lxicos, para ciertas construcciones de lenguajes de programaci n, necesitan ver adelantadamente ms all del final de un lexema antes de que puedan determinar un to/en con certeza. En !ex, se puede escribir un patr n de la forma r1/r2, donde r1 y r2 son expresiones regulares, que significa que una cadena se corresponde con r1, pero s lo si est seguida por una cadena que se corresponde con r2. !a expresi n regular r2, despus del operador lookahead 676, indica el contexto derecho para una correspondencia8 se usa &nicamente para restringir una correspondencia, no para ser parte de la correspondencia. Rec!peraci)n de errore% lexico r+,ico%- !os programas pueden contener diversos tipos de errores, que pueden ser'
Errore% lexico r+,ico%- 9ue veremos a continuaci n. Errore% %in(+c(ico%- (or ejemplo, una expresi n aritmtica con mayor numero de parntesis de apertura que de cierre. Errore% %em+n(ico%- (or ejemplo, la aplicaci n de un operador a un tipo de datos incompatible con el mismo. Errore% l) ico%- (or ejemplo, un bucle sin final.
)uando se detecta un error, un compilador puede detenerse en ese punto e informar al usuario, o bien desechar una serie de caracteres del texto fuente y continuar con el anlisis, dando al final una lista completa de todos los errores detectados. En ciertas ocasiones es incluso posible que el compilador corrija el error, haciendo una interpretaci n coherente de los caracteres le"dos. En estos casos, el compilador emite una advertencia, indicando la suposici n que ha tomado, y contin&a el proceso sin afectar a las sucesivas fases de compilaci n.
!os errores lexicogrficos se producen cuando el analizador no es capaz de generar un to/en tras leer una determinada secuencia de caracteres. En general, puede decirse que los errores lexicogrficos son a los lenguajes de programaci n lo que las faltas de ortograf"a a los lenguajes naturales. !as siguientes situaciones producen con frecuencia la aparici n de errores lexicogrficos' 0. Lec(!ra de !n car+c(er .!e no per(enece al /oca0!lario (erminal pre/i%(o para el a!()ma(a. !o ms normal en este caso es que el aut mata ignore estos caracteres extra#os y contin&e el proceso normalmente. (or ejemplo, pueden dar error en la fase de anlisis lexicogrfico la inclusi n de caracteres de control de la impresora en el programa fuente para facilitar su listado. 3. Omi%i)n de !n car+c(er. (or ejemplo, si se ha escrito ELS en lugar de ELSE. :. Se 1a in(rod!cido !n n!e/o car+c(er. (or ejemplo, si escribimos ELSSE en lugar de ELSE. ;. 2an %ido perm!(ado% do% carac(ere% en el (o*en anali3ado. (or ejemplo, si escribiramos ESLE en lugar de ELSE. 5. 4n car+c(er 1a %ido cam0iado. (or ejemplo, si se escribiera E!<E en vez de E!SE. !as tcnicas de recuperaci n de errores lexicogrficos se basan, en general, en la obtenci n de los distintos sin nimos de una determinada cadena que hemos detectado como err nea. (or otra parte, el analizador sintctico es capaz en muchos casos de avisar al analizador lexicogrfico de cul es el to/en que espera que ste lea. (ara el ejemplo de borrado de un caracter, tenemos que los sin nimos de E!SE son E!S, E!E, ESE, y !SE. (or tanto, si incluimos en nuestro analizador una rutina de recuperaci n de errores debidos a omisi n de caracteres, cualquiera de estos sin nimos ser"a aceptado en lugar del lexema E!SE, se emitir"a la correspondiente advertencia, y el proceso continuar"a asumiendo que se ha le"do el to/en =pal>res>E!SE?. 5nlogamente, podemos incluir rutinas para los dems casos. (or ejemplo, si el analizador lee el lexema ES!E, y no puede construir un to/en correcto para l mismo, proceder"a a generar los sin nimos por intercambio de caracteres @es decir, SE!E, E!SE o ESE!A y comprobar"a si alguno de ellos es reconocible. En
caso afirmativo, genera el to/en correspondiente y advierte al usuario del posible error y de su interpretaci n automtica, continuando con el proceso. Bodos los procedimientos para la recuperaci n de errores lexicogrficos son en la prctica mtodos espec"ficos, y muy dependientes del lenguaje que se pretende compilar.
INTROD4CCIN
El lex es un generador de programas dise#ado para el proceso lxico de cadenas de caracteres de input. El programa acepta una especificaci n, orientada a resolver un problema de alto nivel para comparar literales de caracteres, y produce un programa ) que reconoce expresiones regulares. Estas expresiones las especifica el usuario en las especificaciones fuente que se le dan al lex. El c digo lex reconoce estas expresiones en una cadena de input y divide este input en cadenas de caracteres que coinciden con las expresiones. En los bordes entre los literales, se ejecutan las secciones de programas proporcionados por el usuario. El fichero fuente lex asocia las expresiones regulares y los fragmentos de programas. (uesto que cada expresi n aparece en el input del programa escrito por el lex, se ejecuta el fragmento correspondiente. El usuario proporciona el c digo adicional necesario para completar estas funciones, incluyendo c digo escrito por otros generadores. El programa que reconoce las expresiones se genera en forma de fragmentos de programa ) del *suario, El lex no es un lenguaje completo sino un generador que representa una )ualidad de un nuevo lenguaje que se a#ade al leguaje de programaci n ). El lex convierte las expresiones y acciones del usuario @llamadas fuente en este cap"tuloA en un programa ) llamado yylex. El programa yylex reconoce expresiones en un flujo @llamado input en este cap"tuloA y lleva a cabo las acciones especificadas para cada expresi n a medida que se va detectando. )onsidere un programa para borrar del input todos los espacios en blanco y todos los tabuladores de los extremos de las l"neas. !as l"neas siguientes' CC DbE tFG H8 es todo lo que se requiere. El programa contiene un delimitado CC para marcar el principio de las rdenes, y una orden. Esta orden contiene una expresi n que coincide con una o ms apariciones de los caracteres espacio en blanco o tabulador @escrito E t para que se vea con mayor claridad, de acuerdo con la convenci n del lenguaje )A justo antes del final de una l"nea. !os corchetes indican la clase del carcter compuesto de espacios en blanco y
tabuladores8 el G indica uno o ms del item anterior8 y el signo de d lar @HA indica el final de la l"nea. +o se especifica ninguna acci n, por lo tanto el programa generado por el lex ignorar estos caracteres. Bodo lo dems se copiar. (ara cambiar cualquier cadena de caracteres en blanco o tabuladores que queden en un solo espacio en blanco, a#ada otra orden' CC DbE tFGH8 DbE tF G printf @I JA8 !a automatizaci n generada por este fuente explora ambas rdenes a la vez, observa la terminaci n de la cadena de espacios o tabuladores haya o no un carcter neKline, y despus ejecuta la acci n de la orden deseada. !a primera orden coincide con todas las cadenas de caracteres de espacios en blanco o tabuladores hasta el final de las l"neas, y la segunda orden coincide con todos los literales restantes de espacios o tabuladores. El lex se puede usar s lo para transformaciones sencillas, o por anlisis o estad"sticas buscando en un nivel lxico. El lex tambin se puede usar con un generador reconocedor para llevar a cabo la fase de anlisis lxico8 es especialmente fcil hacer que el lex y el yacc funcionen juntos. !os programas lex reconocen s lo expresiones regulares8 yacc escribe reconocedores que aceptan una amplia clase de gramticas de texto libre, pero que requieren un analizador de nivel bajo para reconocer to/ens de input. (or lo tanto, a menudo es conveniente una combinaci n del lex y del yacc. )uando se usa como un preprocesador para un generador, el lex se usa para dividir el input, y el generador de reconocimiento asigna una estructura a las piezas resultantes. !os programas adicionales, escritos por otros generadores o a mano, se pueden a#adir fcilmente a programas que han sido escritos por el lex. !os usuarios del yacc se darn cuenta de que el nombre yylex es el que el yacc da a su analizador lxico, de forma que el uso de este nombre por el lex simplifica el interface. El lex genera un aut mata finito partiendo de expresiones regulares del fuente. El aut mata es interpretado, en vez de compilado, para ahorrar espacio. El resultado es todav"a un analizador rpido. En particular, el tiempo que utiliza un programa lex para reconocer y dividir una cadena de input es proporcional a la longitud del input. El n&mero de rdenes lex o la complejidad de las rdenes no es importante para determinar la velocidad, a no ser que las rdenes que incluyan contexto posterior requieran una cantidad importante de exploraci n. !o que aumenta con el n&mero y complejidad de las rdenes es el tama#o del aut mata finito, y por lo tanto el tama#o del programa generado por el lex. En el programa escrito por el lex, los fragmentos del usuario @representando acciones que se van a llevar a cabo a medida que se encuentra cada expresi nA se colectan como casos de un intercambio. El intrprete del aut mata dirige el
flujo de control. Se proporciona la oportunidad al usuario para insertar declaraciones o sentencias adicionales en la rutina que contiene las acciones, o para a#adir subrutinas fuera de esta rutina de acci n. El lex no est limitado a fuente que se puede interpretar sobre la base de un posible carcter. (or ejemplo, si hay dos rdenes una que busca ab y la otra que busca abcdefg, y la cadena de caracteres del input es abcdefh, el lex reconocer ab y dejar el puntero del input justo delante de cd. Bal precauci n es ms costosa que el proceso de lenguajes ms sencillos.
se desea cambiar un n&mero de palabras de la ortograf"a Nritnica a la 5mericana. !as rdenes lex tales como colour printf@IcolorJA8 mechanise printf@ImechanizeJA8 petrol printf@IgasJA8 ser una forma de empezar. Estas rdenes no son suficientes puesto que la palabra petroleum se convertir en gaseum8 una forma de proceder con tales problemas se describe en una secci n posterior.
Se reconocen barios escapes ) normales con la barra invertida @EA' E n neKline E t tabulador E b bac/space E E barra invertida (uesto que el carcter neKline es ilegal en una expresi n, es necesario usar n8 no se requiere dar escape al carcter tabulador y el bac/space. )ada carcter excepto el espacio en blanco, el tabulador y el neKline y la lista anterior es siempre un carcter de texto.
LLAMAR AL LEX.
Qay dos pasos al compilar un programa fuente lex (rimero, el programa lex fuente tiene que ser convertido en un programa regenerado en el lenguaje de prop sito general. Entonces ste programa tiene que ser compilado y cargado, normalmente con una librer"a de subrutinas lex. El programa generado est en un fichero llamado lex.yy.c. !a librer"a $7L est definida en trminos de la librer"a estndar ). 5 la librer"a se accede por medio del flag de la carga Mll. (or lo tanto un conjunto de comandos apropiados es lex source cc lex.yy.c Rll .El programa resultante se pone en el fichero usual a.out para ser ejecutado posteriormente. (ara usar el lex con el yacc ver la secci n I lex y SaccJ de este cap"tulo y en el capitulo T, I Sacc' el )ompiladorM)ompiladorJ, 5unque las rutinas $7L por defecto del lex usan la librer"a estndar ), el aut mata del lex no lo hace. Si se especifican las versiones privadas de input, output, y unput, la librer"a se puede evitar.
ignoran. S lo tres caracteres son especiales' stos son la barra invertida @ 7 A, el gui n @ ; A, y el signo de intercalaci n @ : A. El carcter gui n indica rangos, por ejemplo D aMzUMT=?> F
!a expresi n ab7cd coincide con el literal ab, pero s lo si va seguido de cd. (or lo tanto abH es lo mismo que ab7En. El contexto de la izquierda se maneja en el lex especificando las condiciones start seg&n se explica en la secci n IEspecificaci n de sensibilidad de contexto izquierdo I. Si una orden s lo se va a ejecutar cuando el interprete del aut mata del lex est en la condici n x start, la orden se deber incluir entre corchetes de ngulos' =x? Si consideramos que estamos al comienzo de una l"nea que es el comienzo de la condici n L+E, entonces el operador @ Y A ser equivalente a =L+E? !as condiciones start se explican con detalles ms tarde.
ESPECI5ICAR DE5INICIONES.
!as definiciones se dan en la primera parte del input del lex, antes de las rdenes. En contraste, a10,O2 busca de una a cinco apariciones del carcter IaJ..inalmente, un signo de tanto por ciento inicial @ C A es especial puesto que es el separador para los segmentos fuente del lex.
ESPECI5ICACIN DE ACCIONES.
)uando una expresi n coincide con un modelo de texto en el input el lex ejecuta la acci n correspondiente. Esta secci n describe algunas caracter"sticas del lex, las cuales ayudan a escribir acciones. + tese que hay una acci n por defecto, la cual consiste en copiar el input en el output. Esto se lleva a cabo en todos los literales que de otro modo no coincidir"an. (or lo tanto el usuario del lex que desee absorber el input completo, sin producir ning&n output, debe proporcionar rdenes para hacer que coincida todo. )uando se est usando el lex con el yacc, sta es la situaci n normal. Se puede tener en cuenta qu acciones son las que se hacen en vez de copiar el input en el output8 por lo tanto, en general, una orden que simplemente copia se puede omitir. *na de las cosas ms simples que se pueden hacer es ignorar el input. Especificar una sentencia nula de )8 como una acci n produce este resultado.
!a orden frecuente es D E t E nF 8 la cual hace que se ignoren tres caracteres de espaciado @espacio en blanco, tabulador, y neKlineA. Ltra forma fcil de evitar el escribir acciones es usar el carcter de repetici n de acci n, W , el cual indica que la acci n de esta orden es la acci n para la orden siguiente. El ejemplo previo tambin se pod"a haber escrito' I J W IE tJ W IE nJ 8 con el mismo resultado, aunque en un estilo diferente. !as comillas alrededor deE n y E t no son necesarias. En acciones ms complejas, a menudo se quiere conocer el texto actual que coincida con algunas expresiones como' D aMz F G El lex deja este texto en una matriz de caracteres externos llamada FF(ext. (or lo tanto, para imprimir el nombre localizado, una orden como D aMz F G printf @ICsJ , yytextA8 imprime el literal de yytext. !a funci n ) printf acepta un argumento de formato y datos para imprimir8 en este caso , el formato es print literal donde el signo de tanto por ciento @ C A indica conversi n de datos, y la s indica el tipo de literal, y los datos son los caracteres de yytext. (or lo tanto esto simplemente coloca el literal que ha coincidido en el output. Esta acci n es tan com&n que se puede escribir como E)QL.
ESPECI5ICACIN DE SENSIIILIDAD DE CONTEXTO IZJ4IERDO 5 veces es deseable aplicar varios grupos de rdenes lxicas en diferentes ocasiones en el input. (or ejemplo, un compilador preprocesador puede distinguir sentencias del preprocesador y analizarlas de forma diferente a como hace con las sentencias ordinarias. Esto requiere sensitividad al contexto previo, y hay varias formas de tratar tales problemas. El operador @ Y A, por ejemplo, es un operador de contexto previo, que reconoce inmediatamente contexto que precede por la izquierda del mismo modo que el signo de d lar @ H A reconoce el contexto que va inmediatamente a la derecha. El contexto adyacente a la izquierda se podr"a extender, para producir un dispositivo similar al del contexto adyacente a la derecha, pero no es muy probable que sea de utilidad, puesto que a menudo el contexto de la derecha relevante apareci alg&n tiempo antes tal como al principio de una l"nea. Esta secci n describe tres formas de tratar con entornos diferentes' 0. El uso de flags, cuando de un entorno a otro s lo cambian unas pocas rdenes. 3. El uso de condiciones start con rdenes. :. El uso de diversos analizadores lxicos funcionando juntos. En cada caso, hay rdenes que reconocen la necesidad de cambiar el entorno en el cual se analiza el texto de input siguiente, y ponen varios parmetros para reflejar el cambio. Esto puede ser un flag probado expl"citamente por el c digo de acci n del usuario8 tal flag es una forma ms sencilla de tratar con el problema, puesto que el lex no est relacionado. (uede que sea ms conveniente, hacer que el lex recuerde los flags como condiciones iniciales de las rdenes. )ualquier orden puede estar relacionada con una condici n start. S lo ser reconocida cuando el lex est en esa misma condici n. !a condici n de start en curso se puede cambiar en cualquier momento. .inalmente, si los conjuntos de rdenes de los diferentes entornos son muy diferentes, se puede lograr una mayor claridad escribiendo varios analizadores
lxicos distintos, y cambiar de uno a otro seg&n se desee. )onsidere el siguiente problema' copie el input en el output, cambiando la palabra ImagicJ a IprimeroJ en cada l"nea que comience con la letra a, cambiando ImagicJ por IsegundoJ en cada l"nea que comience con la letra b, y cambiando ImagicJ por IterceroJ en cada l"nea que comience con la letra c. ESPECI5ICACIN DE DE5INICIONES 54ENTE Zecuerde el formato de la fuente lex 1 definiciones 2 CC 1 rdenes 2 CC 1 rutinas del usuario 2 Qasta ahora s lo se han descrito las rdenes. Se necesitarn opciones adicionales, para definir variables para usarlas en el programa y para que las use el lex. Estas pueden ir bien en la secci n de definiciones o en la secci n de rdenes. 0. )ualquier l"nea que no aparezca como una orden o acci n de lex, la cual comienza con un espacio en blanco o un tabulador se copia en el programa generado. Bal input de fuente antes del primer delimitador CC ser externo a cualquier funci n del c digo8 si aparece inmediatamente despus del primer C C, aparece en un lugar apropiado para las declaraciones en la funci n escrita por el lex el cual contiene las acciones. Este material tiene que buscar fragmentos de programas, y deber ir delante de la primera orden de lex. )omo efecto secundario de lo anterior, las l"neas que comienzan con un espacio en blanco o un tabulador, y las cuales contienen un comentario, se pasan al programa generado. Esto se puede usar para incluir comentarios bien en la fuente lex o bien en el c digo generado. !os comentarios debern seguir las convenciones del lenguaje ). 3. )ualquier cosa que vaya incluida entre l"neas que s lo contienen C 1 y C 2 se copia como en el anterior. !os delimitadores se desechan. Este formato permite introducir texto como sentencias de preprocesador que deben comenzar en la columna 0, o copiar l"neas que no parecen programas.
LEX # #ACC
Si se quiere usar el lex con el yacc, tngase en cuenta que el lex escribe un programa llamado yylex@ A, el nombre requerido por el yacc para su analizador. +ormalmente el programa main por defecto de la librer"a lex llama a esta rutina, pero si yacc est cargado, y se usa su programa main, yacc llamar al yylex@ A. En este caso, cada orden lex deber terminar con return @to/enA8 donde se devuelve el valor de to/en apropiado. *na forma fcil de obtener acceso a los nombres del yacc para los to/ens es compilar el fichero de output del lex como parte del fichero de output del yacc poniendo la l"nea [include Ilex.yy.cJ en la <ima secci n del input del yacc. Suponiendo que la gramtica se llama IgoodJ y las rdenes lxicas se llamen IbetterJ , la secuencia de comandos ,E+$, puede ser' yacc good, lex better, cc y.tab.c Rly Rll. !a librer"a yacc @MlyA se deber cargar antes de la librer"a lex para obtener un programa main que llame al reconocedor yacc. !a generaci n de programas lex y yacc se puede hacer en cualquier orden. )omo problema trivial, considere copiar un fichero input mientras se a#ade : a cada n&mero positivo divisible por P. (odemos desarrollar un programa fuente lex que hace precisamente eso' CC int /8 D UMT FG 1 / \ atoi@yytextA8 if @/CP \\ UA printf@ICdJ,/G:A8 else printf@ICdJ, /A8 2 !a orden D UMT FG reconoce cadenas de d"gitos8 atoi@ A convierte los d"gitos en binario y almacena el resultado en /. El operador @CA se usa para comprobar si / es divisible por P8 si lo es, se incrementa en : a medida que se va escribiendo. Se puede objetar que este programa alterar input tal como ;T.]: o ,P. 5dems incrementa el valor absoluto de todos los n&meros negativos divisible por P. (ara evitar esto, a#ada simplemente unas pocas ms de rdenes despus de la orden activa, como'
CC int /8 MX D U RT FG 1 / \ atoi@yytestA8 printf@ICdJ,/CP \\ UX ^G: ' /A8 2 MX D UMT FG E)QL8 D5M<aMzF D5M<aMzUMT FG E)QL8 !as cadenas de caracteres numricos que contienen un punto decimal o precedidas de una letra sern cogidas por una de las dos rdenes, y no se cambiarn. Si el ifMelse ha sido cambiado por una expresi n condicional ) para ahorrar espacio8 la forma aXb'c quiere decir' si a entonces b, en caso contrario c. )omo ejemplo de obtenci n de estad"sticas, aqu" hay un programa que hace histogramas de longitudes de palabras, donde una palabra est definida como una cadena de letras. int lengsD0UUF8 CC D aMz F G lengsDyylengFGG8 . W En K CC yyKrap@ A 1 int i8 printf@I!ength +o. KordsEnJA8 for@i\U8 i=0UU8 iGGA if @lengsDiF ? UA printf@ICOdC0UdEnJ,i,lengsDiFA8 return @0A8 2 Este programa acumula el histograma, pero no produce output. 5l final del input imprime una tabla. !a sentencia final return @0A8 indica que el lex va a llevar a cabo un Krapup. Si yyKrap@ A devuelve un valor cero @falseA implica que hay disponible ms input y el programa va a continuar leyendo y procesando. *n yyKrap@ A que nunca devuelve un valor verdadero produce un bucle infinito.
5ORMATO 54ENTE
El formato general de un fichero fuente del lex es' 1definiciones2 CC 1 rdenes2 CC 1subrutinas del usuario2 !a secci n de definiciones contiene una combinaci n de 0. 4efiniciones en el formato Inombre espacio traducci nJ. 3. ) digo incluido, en el formato I espacio c digo J. :. ) digo incluido en el formato C1 c digo C2 ;. )ondiciones start, especificadas en el formato CS nombre0, nombre3, ... O. Bablas del conjunto de caracteres, en el formato CB numero espacio cadena de caracteres CB ]. )ambia los tama#os de las matrices internas, en el formato Cx nnn donde nnn es un n&mero entero decimal que representa un tama#o de matriz y x selecciona el parmetro de la forma siguiente' !etra (armetro p posiciones n estados e nudos de rbol a transiciones / )lases de caracteres compactados o tama#o de la matriz de output !as l"neas en la secci n de rdenes tienen la forma expresi n acci n donde la acci n se puede continuar en las l"neas siguientes usando llaves para delimitarlo. !as expresiones regulares del lex usan los operadores siguientes' x El carcter I x I IxJ *na IxJ, incluso si x es un operador. Ex *na IxJ, incluso si x es un operador.
DxyF El carcter x o y. DxMzF !os caracteres x, y o z. DY xF )ualquier carcter salvo x. . )ualquier carcter salvo neKline. Y x *na x al principio de la l"nea. =y?x *na x cuando el lex est en la condici n start y. xH *na x al final de una l"nea. xX *na x opcional. xV U,0,3 .... apariciones de x. xG 0,3,: .... apariciones de x. xWy *na x o una y. x7y *na x, pero s lo si va seguida de una y. 1xx2 !a traducci n de xx de la secci n de definiciones. x1m,n2 m a travs de n ocurrencias de x.
Generador
E Especificaci n de las caracter"sticas del lenguaje ! 5 5nalizador para ! !os generadores !ex y Sacc sirven, respectivamente, para generar analizadores lexicogrficos y analizadores sintcticos para su aprovechamiento como partes de los compiladores de los lenguajes de programaci n8 estos usos de !ex y Sacc no son los &nicos, aunque s" son los que aqu" se consideran principalmente. (ara entender cabalmente el funcionamiento de los generadores de analizadores, hay que conocer la teor"a de compiladores relacionada con las tareas de anlisis de lenguajes.
)uando se emplea el trmino !ex, se mencionan dos posibles significados' aA una notaci n para especificar las caracter"sticas lexicogrficas de un lenguaje de programaci n, bA un traductor de especificaciones lexicogrficas. Esta misma dualidad tambin es de aplicaci n al trmino Sacc. Esquema de uso El esquema de la pgina siguiente ilustra la manera de usar los generadores !ex y Sacc para obtener un analizador lxicoMsintctico de un lenguaje de programaci n !, y de ejecutar el analizador obtenido. !os nombres que aparecen en el esquema significan' e!exic.l es la especificaci n de las caracter"sticas lexicogrficas del lenguaje !, escrita en !ex eSint.y es la especificaci n de las caracter"sticas sintcticas del lenguaje !, escrita en Sacc lex.yy.c es el analizador lexicogrfico de ! generado por !ex8 est constituido, en su parte principal, por una funci n escrita en ) que realiza las tareas de anlisis lexicogrfico basndose en aut matas regulares reconocedores de la forma de las piezas sintcticas de ! libl es una librer"a asociada a !ex que contiene estructuras de datos y funciones a las que se puede hacer referencia desde el c digo generado liby es una librer"a asociada a Sacc con la misma utilidad que la anterior y.tab.c es el analizador sintctico generado por Sacc8 est constituido, en su parte principal, por una funci n escrita en ) que realiza las tareas de anlisis sintctico seg&n el mtodo ascendente !5!Z@0A, basado en tablas
eLexic.l
lex.yy.c
lex
Compilador Montador
de
C
yacc
eSint.y
y.tab.c
anLeSi
sintcticas especificadas del lenguaje !8 acepta como entrada un programa escrito en ! y comprueba si est codificado seg&n las especificaciones dadas ( programa escrito en el lenguaje ! +o es preciso que los nombres de los ficheros de entrada para !ex y Sacc tengan una extensi n determinada8 los nombres de los ficheros generados por !ex y Sacc son siempre los indicados, con independencia de cul sea el nombre de los ficheros de entrada.
Lbtenci n y ejecuci n del analizador El analizador lxicoMsintctico se obtiene tras la realizaci n de los siguientes pasos' 0A vi e!exic.l edici n del fichero con las caracter"sticas lexicogrficas 3A vi eSint.y edici n del fichero con las caracter"sticas sintcticas :A lex e!exic.l traducci n de las caracter"sticas lexicogrficas ;A yacc eSint.y traducci n de las caracter"sticas sintcticas OA cc lex.yy.c y.tab.c Rll Rly Ro an!eSi compilaci n del c digo de los analizadores generados @El orden de pasos citado es una posibilidad, no una necesidad8 se ha supuesto el uso del editor viA. !os ficheros sobre los que act&a el analizador lxicoMsintctico generado son @salvo que de manera expl"cita se indique otra cosaA los preMdefinidos de entrada y de salida8 as" pues, la ejecuci n del analizador obtenido puede hacerse de una las siguientes formas' an!eSi an!eSi =Entrada an!eSi =Entrada ?Salida Seg&n que se haga o no reMdireccionamiento de los ficheros de entrada y de salida preMdefinidos. En el fichero de entrada se proporciona un programa escrito en !. !a salida, que debe de informar sobre el resultado del anlisis, puede ser ms o menos elaborada8 por ahora se considera la posibilidad ms sencilla. Si el programa analizado es correcto en lo que respecta al lxico y a la sintaxis, no se emite indicaci n alguna8 si el programa no es correcto porque tiene alg&n error lexicogrfico o sintctico, se emite el mensaje syntax error @ms adelante se justificar la raz n por la que se emite este mensaje, tanto si se trata de un error lexicogrfico como si es uno sintcticoA.
E"emplo L
)on este ejemplo inicial se muestra, antes de empezar el estudio detallado, una aplicaci n de los generadores !ex y Sacc para obtener un analizador lxicoM sintctico de un lenguaje simple. Se proporciona la soluci n sin explicaci n alguna8 lo &nico que se pretende ahora es obtener automticamente un analizador, y probar su funcionamiento. Se trata de una clase sencilla de expresiones aritmticas en las que pueden encontrarse' M variables @nombres escritos en min&sculas, de cualquier longitudA, M constantes @n&meros con cifras decimales de cualquier longitudA, M operadores @ >, =A, M parntesis. !a sintaxis de las expresiones se define mediante la siguiente gramtica @escrita en notaci n N+.M5mpliadaA' =Expresion? ''\ =Bermino? D > =Bermino? E =Bermino? ''\ =.actor? D = =.actor? E =.actor? ''\ @ =Expresion? A W id W c(e !a entrada a !ex @la especificaci n lexicogrficaA, si se emplean los nombres p$d, p)te, pSum, p_ul, p5br y p)er para representar las distintas piezas sintcticas del lenguaje, es'
C1 [define p$d 0 [define p)te 3 [define pSum : [define p_ul ; [define p5br O [define p)er ] [define Error TTT C2 CC DaMzFG 1 return p$d8 2 DUMTFG 1 return p)te8 2 6G6 1 return pSum8 2 6V6 1 return p_ul8 2 6@6 1 return p5br8 2 6A6 1 return p)er8 2 DE EtEnF 1 8 2 . 1 return Error8 2 !a entrada a Sacc @la especificaci n sintcticaA es, considerada a partir de una gramtica equivalente a la dada, pero escrita en notaci n N+.M+o ampliada, es' Cto/en p$d 0 Cto/en p)te 3 Cto/en pSum : Cto/en p_ul ; Cto/en p5br O Cto/en p)er ] Cstart Expresion CC Expresion ' Bermino ZestoExpr 8 ZestoExpr ' pSum Bermino ZestoExpr 8 W 8 Bermino ' .actor ZestoBerm 8 ZestoBerm ' p_ul .actor ZestoBerm 8 W 8 .actor ' p$d 8 W p)te 8
W p5br Expresion p)er 8 CC main @A 1 yyparse @A8 2 !a raya vertical puesta a la izquierda de las dos especificaciones representa la posici n de la primera columna de las l"neas de los ficheros de tipo texto. Si el analizador obtenido se aplica a la entrada @x G yA V cota, que es una expresi n correcta, no se obtiene mensaje alguno como resultado del anlisis8 si se aplica a la entrada xGyVGz, que es una expresi n incorrecta, se obtiene como salida la indicaci n syntax error8 si se aplica a la entrada x G yX R z, que contiene un carcter que no pertenece al alfabeto @error lexicogrficoA, tamM bin se obtiene el resultado syntax error.