compilador lex

8
INSTITUTO TECNOLOGICO SUPERIOR DE LIBRES INGENIERIA EN SISTEMAS COMPUTACIONALES ALUMNA: ANDREA VELAZQUEZ RICO TRABAJO: COMPILADOR LEX MATERIA: PROGRAMACION DE SISTEMAS MAESTRA: DIANA MARICELA 5to. “A” Fecha: 3/octubre/2011

Upload: andrea-velazquez

Post on 20-Mar-2016

213 views

Category:

Documents


0 download

DESCRIPTION

compilador

TRANSCRIPT

Page 1: COMPILADOR LEX

INSTITUTO TECNOLOGICO SUPERIOR DE LIBRES

INGENIERIA EN SISTEMAS

COMPUTACIONALES

ALUMNA: ANDREA VELAZQUEZ RICO

TRABAJO: COMPILADOR LEX

MATERIA: PROGRAMACION DE SISTEMAS

MAESTRA: DIANA MARICELA

5to. “A”

Fecha: 3/octubre/2011

Page 2: COMPILADOR LEX

COMPILADORES “Un compilador es un programa que lee un programa escrito en un lenguaje, y lo traduce a un programa equivalente en otro lenguaje.” Durante la traducción el compilador informa de la presencia de errores en el programa fuente.

ANÁLISIS LÉXICO Convierte una cadena de caracteres que conforma el programa fuente en un grupo de “palabras”, que son secuencias de caracteres con significado propio. Ejemplo: if Existe then

posicion:=60;

end if;

1. la palabra reservada “if”

2. la expresión booleana “Existe”

3. la palabra reservada “then”

4. el identificador “posicion”

5. el símbolo de asignación “:=”

6. la constante “60”

7. el final de instrucción “;”

8. la palabra reservada “end”

9. la palabra reservada “if”

10. el final de instrucción “;”

LEX LEX es un generador de programas diseñado para el proceso léxico 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 C 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

HIATORIA En 1975, con la aparición de LEX surge el concepto de un generador automático de analizadores léxicos a partir de expresiones regulares, basado en el sistema operativo UNIX. A partir de los trabajos de Chomsky ya citados, se produce una sistematización de la sintaxis de los lenguajes de programación, y con ello un desarrollo de diversos métodos de análisis sintáctico. FLEX es una herramienta para generar escáneres: programas que reconocen patrones léxicos en un texto. Flex lee los ficheros de entrada dados, o la entrada estándar si no se le ha indicado ningún nombre de fichero, con la descripción de un escáner a generar.

EL CONSTRUCTOR DE ANALIZADORES

LÉXICOS LEX LEX es un constructor de analizadores léxicos.

Page 3: COMPILADOR LEX

Opera mediante una descripción de la gramática hecha mediante expresiones regulares. Genera un programa en lenguaje C que sirve como analizador léxico. Existe un equivalente en lenguaje Ada: aflex

Lex es una herramienta que se ha utilizado para especificar analizadores léxicos para una variedad de lenguajes. Normalmente se le llama compilador Lex a la herramienta, y lenguaje Lex a sus especificaciones de entrada. Existe un equivalente a “lex” en Ada, denominado “aflex”. La herramienta lex genera un programa C que sirve como analizador léxico; aflex genera también un analizador léxico, pero en lenguaje Ada. Generalmente lex o aflex se utilizan de la siguiente forma: Primero se prepara una especificación de la gramática en lenguaje Lex.

Posteriormente, se utiliza la herramienta para producir el código fuente del

programa analizador léxico. Este código fuente debe ser compilado, lo que produce el analizador léxico. Con el analizador léxico resultante, se puede realizar el análisis léxico de un

código fuente tantas veces como sea necesario. La herramienta aflex crea ficheros Ada terminados en “.a”, que por tanto no se

adhieren a las convenciones de nombres del compilador gnat. Además, crea los paquetes en un solo fichero, con la especificación y el cuerpo en el mismo fichero. Esto también es contrario a las reglas del gnat.

Para estas situaciones, existe una herramienta llamada “gnatchop”, que

permite crear los ficheros con los nombres apropiados, a partir de otros ficheros.

En el caso del ejemplo de la figura, habrá que ejecutar: gnatchop -w name.a

gnatchop -w name_dfa.a

gnatchop -w name_io.a

Donde “name” es el nombre de la especificación lex original. Luego hay que construir el ejecutable:

gnatmake name

ESPECIFICACIONES EN LEX Definiciones: Las definiciones son definiciones regulares que

toman la forma: nombre expresión_regular POR EJEMPLO: letra [a-zA-Z]

digito [0-9]

identificador {letra}({letra}|{digito}|_)*

Page 4: COMPILADOR LEX

Reglas de traducción: se describen de la forma: patrón {acción} Patrón es una expresión regular; Acción es un trozo de código.

Código auxiliar

Estructura del código auxiliar El código auxiliar se escribe con la estructura: sección inicial de código

##

sección final de código

El código Ada generado tendrá la estructura siguiente: with Name_Dfa, Name_IO, Text_IO;

sección inicial de código (debe incluir el tipo Token)

function YYLex return Token is

begin

-- definida por la herramienta lex

end;

sección final de código

Un ejemplo de código auxiliar:

procedure Name is

type Token is (End_Of_Input, Error);

Tok : Token;

##

begin

while Tok /= End_of_Input loop

Tok:=YYLex;

end loop;

end Name;

La función YYLex se crea automáticamente, y se coloca en el lugar donde se han escrito los caracteres ##. Para que esta función sea válida, es imprescindible que en la sección inicial de código se haya creado el tipo enumerado Token, con al menos los dos valores End_Of_Input y Error.

ASPECTOS A TENER EN CUENTA EN

LA ESPECIFICACIÓN LEX El texto que verifica el patrón de una regla de traducción se puede obtener con la

función predefinida YYText.

Es habitual que el código de una regla de traducción acabe con una instrucción:

return valor; donde valor es un valor del tipo enumerado Token, creado en la

sección inicial de código auxiliar. Esto es especialmente habitual si se enlaza lex

con yacc (analizador sintáctico) Cuando un string puede cumplir dos reglas de

traducción, se elige: 1. El string más largo

Page 5: COMPILADOR LEX

2. Si son iguales, la regla que aparece en primer lugar.

Ejemplo con lex El siguiente ejemplo convierte un texto con insultos en otro con palabras más “correctas” :-) Especificación Lex, en el fichero bien_educado.l:

-- definiciones

espacio " "|\n

palabra [a-zA-Z]+{espacio}

tonto ("tonto"{espacio})|("ignorante"{espacio})

tonta "tonta"{espacio}

tonto_de "tonto"{espacio}"de"l?{espacio}{palabra}

idiota "idiota"{espacio}

nueva_linea \n

%%

-- reglas de traducción

{tonto} {Put("listo ");}

{tonta} {Put("lista ");}

{idiota} {Put("distinguido ");}

{tonto_de} {Put("amable caballero ");}

{nueva_linea} {New_Line;}

. {Put(YYText);}

%%

-- Código auxiliar inicial

with Ada.Text_IO; Use Ada.Text_IO;

procedure Bien_Educado is

type Token is (end_of_input,error);

tok : token;

Page 6: COMPILADOR LEX

OTRA DEFINICIÒN

Lex

Lex es un programa para generar analizadores léxicos (en inglés scanners o lexers).

Lex se utiliza comúnmente con el programa yacc que se utiliza para generar análisis

sintáctico. Lex, escrito originalmente por Eric Schmidt y Mike Lesk, es el analizador

léxico estándar en los sistemas Unix, y se incluye en el estándar de POSIX. Lex toma

como entrada una especificación de analizador léxico y devuelve como salida el

código fuente implementando el analizador léxico en C.

Aunque tradicionalmente se trata de software propietario, existen versiones libres de lex basadas en el código original de AT&T en sistemas como OpenSolaris y Plan 9 de los laboratorios Bell. Otra versión popular de software libre de lex es Flex.

Estructura de un archivo de lex

La estructura de un archivo de lex es intencionadamente similar a la de un archivo del yacc; los archivos se dividen en tres secciones, separadas por líneas que contienen solamente dos símbolos "%", como sigue:

Sección de declaraciones

%%

Sección de reglas

%%

Sección de código en C

La sección de declaraciones es el lugar para definir macros y para importar los archivos de cabecera escritos en C. También es posible escribir cualquier código de C aquí, que será copiado en el archivo fuente generado. Este código en C debe ir entre los símbolos %{ %}.

También se pueden incluir "atajos" para definir patrones de la Sección de Reglas, por ejemplo en vez del patrón [0-9]* (cero o más dígitos que reconocerían cualquier número natural), se puede definir en esta sección el "atajo": números [0-9]*, así, en la sección de código pondríamos el patrón {números} {acción_en_C;}. Con esto se clarifica la escritura del código en lex.

La sección de reglas es la sección más importante; asocia patrones a sentencias de C. Los patrones son simplemente expresiones regulares. Cuando el lexer encuentra un texto en la entrada que es asociable a un patrón dado, ejecuta el código asociado de C. Ésta es la base de del funcionamiento de lex.

La sección de código C contiene sentencias en C y funciones que serán copiadas en el archivo fuente generada. Estas sentencias contienen generalmente el código llamado por las reglas en la sección de las reglas. En

Page 7: COMPILADOR LEX

programas grandes es más conveniente poner este código en un archivo separado y enlazarlo en tiempo de compilación.

Ejemplo de archivo Flex

Lo siguiente es un ejemplo de archivo lex para la versión Flex de lex. Reconoce cadenas de números (números enteros) en la entrada, y simplemente los imprime en la salida.

/*** Sección de declaraciones ***/

%{

/* Código en C que será copiado */

#include <stdio.h>

%}

/* Esto indica a Flex que lea sólo un fichero de entrada */

%option noyywrap

%%

/*** Sección de reglas ***/

/* [0-9]+ identifica una cadena de uno o más dígitos */

[0-9]+ {

/* yytext es una cadena que contiene el texto coincidente.

*/

printf("Encontrado un entero: %s\n", yytext);

}

. { /* Ignora todos los demás caracteres. */ }

%%

/*** Sección de código en C ***/

int main(void)

{

/* Ejecuta el ''lexer'', y después termina. */

yylex();

return 0;

}

Si se da esta entrada a flex, será convertida en un archivo de C, lex.yy.c. Esto se puede compilar en un ejecutable que encuentre y haga salir cadenas de números enteros. Por ejemplo, dando la entrada:

abc123z.!&*2ghj6

El programa imprimirá:

Encontrado un entero: 123

Encontrado un entero: 2

Encontrado un entero: 6

Uso de Lex con Yacc

Page 8: COMPILADOR LEX

Lex y Yacc (un generador de analizadores sintácticos) suelen ser utilizados juntos. Yacc utiliza una gramática formal para analizar un flujo de entradas, algo que Lex no puede hacer con expresiones regulares simples (Lex se limita a los autómatas de estados finitos simples). Sin embargo, Yacc no puede leer en un flujo de entradas simple - requiere una serie de símbolos. Lex se utiliza a menudo para proporcionar a Yacc estos símbolos.

Ejemplos

• Sustituir las palabras ‘el’ y ‘la’, ‘los’ y ‘las’ por la palabra ‘ARTICULO’. %%

el|la|los|las printf ("ARTICULO");

ó %%

el |

la |

los |

las printf ("ARTICULO");

• Lo mismo, pero sin afectar a palabras como ‘lanza’: %%

[Ee]l |

[Ll][oa]s? printf ("articulo");

[A-Za-z]+ ECHO;

• Pasar a mayúsculas los artículos determinados: %%

[Ee]l |

[Ll][ao]s? { int i;

for (i=0;i<yyleng;i++)

printf ("%c",toupper(yytext[i]));

}

• Contar el número de artículos determinados: %{

/* Cuenta el número de artículos determinados */

int num=0;

%}

%%

[Ee]l |

[Ll][oa]s? num++ ;

[A-Za-z]+ ;

.|\n ;

%%

main(){

yylex();

printf ("Número de artículos: %d\n", num);

BIBLIOGRAFIA:

http://www.infor.uva.es/~mluisa/talf/docs/labo/L3.pdf

http://www.slideshare.net/PauNyo/lex-5496077

http://www.ctr.unican.es/asignaturas/lan/compila-2en1.pdf