La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Programación de sistemas

Presentaciones similares


Presentación del tema: "Programación de sistemas"— Transcripción de la presentación:

1 Programación de sistemas
Unidad 4 Análisis léxico

2 Contenido Función del analizador léxico
Aspectos del análisis léxico Componentes léxicos, patrones y lexemas Errores léxicos Manejo de los buffers de entrada Parejas de buffers Centinelas Especificación de los componentes léxicos Cadenas y lenguajes Operaciones aplicadas a lenguajes Expresiones regulares Definiciones regulares Abreviaturas de notación Reconocimiento de los componentes léxicos Diagramas de transición Implantación de un diagrama de transiciones

3 Función del analizador léxico
El análisis léxico constituye la primer fase de cualquier traductor. Su función principal consiste en leer los caracteres de entrada y elaborar como salida una secuencia de componentes léxicos, los cuales serán utilizados por un analizador sintáctico.

4 Función del analizador léxico (2)
Otras funciones secundarias que también realiza un analizador léxico cuando forma parte de un compilador son: Eliminar los comentarios del programa Eliminar los espacios en blanco, tabuladores, retorno de carro, y en general todo aquello que carezca de significado según la sintaxis del lenguaje. Reconocer identificadores de usuario, números, palabras reservadas del lenguaje, etc. y tratarlos correctamente con respecto a la tabla de símbolos. Llevar la cuenta del número de línea que se esta leyendo. Avisar de errores léxicos. Puede realizar funciones de preprocesador

5 Aspectos del análisis léxico
Separar el análisis léxico del sintáctico tiene varias razones: Permite un diseño sencillo Esta es la consideración más importante Simplifica ambas fases, pero sobre todo simplifica el análisis sintáctico. Se construyen dos gramáticas una para el análisis léxico y otra para el sintáctico. Se mejora la eficiencia del compilador Contando con un procesador léxico especializado y potencialmente más eficiente. Utilizando técnicas especializadas para el manejo de buffers. Se mejora la transportabilidad del compilador Limitando al analizador léxico las peculiaridades del alfabeto y los dispositivos de entrada.

6 Componentes léxicos, lexemas y patrones
Token (componente léxico) Conjunto de secuencias de caracteres con la misma misión sintácticamente. Es el terminal asociado a un patrón. Lexema Lo conforman una secuencia de caracteres que encajan con un patrón. Secuencia de caracteres que forman un token. Patrón Regla o reglas que describen a los lexemas pertenecientes a un token. Es una expresión regular Una vez que se ha detectado una secuencia de caracteres que coincide con un patrón, se a detectado un lexema y debe reportarse un número que lo identifica como un cierto tipo de token.

7 Errores léxicos Cuando se trata de analizar un programa fuente el analizador léxico tiene una visión restringida, por lo cual son pocos los errores que se pueden detectar. Sin embargo se debe seguir alguna estrategia para detectar, informar y recuperarse de los errores. Cuando un error ocurre: Es inaceptable si el analizador falla, o se entra en un ciclo infinito. Es una buena estrategia evitar la avalancha de errores, y más aún se debería no solo informar sino tratar de recuperarse del error.

8 Errores léxicos (2) El analizador léxico tiene el mismo comportamiento que un Autómata finito, así la detección de un error se da cuando no existe transición alguna desde el estado actual a otro con el símbolo actual de la entrada. Bajo el enfoque anterior, algunas de las estrategias posibles son: Ir al estado inicial ignorando los símbolos leídos para el lexema. Modo panic, se ignora todo lo desconocido y no se avanza hasta encontrar un símbolo que nos lleve a otro estado. Intentar reparar los errores en los lexemas al borrar, insertar, intercambiar y sustituir símbolos.

9 Manejo de los buffers de entrada
Como el analizador léxico es quien lee el programa fuente desde almacenamiento secundario (por lo regular, caracter a caracter), es probable que se consuma mucho tiempo en esta fase. Es importante considerar el manejo de los buffers de entrada para no demeritar la eficiencia de los traductores, más aún de los compiladores. Existen tres métodos para la implementación de un analizador léxico. Usar un generador de analizadores léxicos (LEX). Codificar el analizador léxico en un lenguaje convencional (lenguaje C). Manejo explícito de la entrada usando lenguaje ensamblador. Las tres opciones se relacionan en orden de dificultad creciente, sin embargo, las implementaciones de mayor dificultad son generalmente las más rápidas.

10 Parejas de buffers Durante el análisis léxico, en la mayoría de los casos, es necesario preanalizar varios caracteres antes de anunciar una concordancia. Para no leer caracter a caracter de la entrada, se utiliza un buffer dividido en dos mitades de N caracteres cada una (N = Tam. Bloque en disco). Se leen N caracteres de entrada en una de las mitades y otras N en la segunda mitad (siempre que sea posible). Dos apuntadores al buffer son necesarios, uno señala el lexema en curso y otro el siguiente. Cuando el apuntador delantero esta por sobrepasar la marca de una de las mitades se leen N caracteres de la entrada nuevamente para la otra mitad. if delantero está al final de la primera mitad then begin recargar la segunda mitad; delantero := delantero + 1; end else if delantero está al final de la segunda mitad then begin recargar la primera mitad; pasar delantero al principio de la mitad else N N L e x 1 l e x 2 l e x 3 l e x 4 Delantero Lexema_en_curso

11 Lex1 lex2 eof lex3 lex4 eof eof
Centinelas El uso de centinelas evita la necesidad de hacer pruebas cada vez que avanza el apuntador delantero. La técnica consiste en ampliar cada mitad del buffer para admitir un caracter centinela al final (comúnmente EOF). N N N N+1 delantero := delantero + 1; if delantero = eof then begin if delantero está al final de la primera mitad then begin recargar la segunda mitad; delantero: = delantero + 1; end else if delantero está al final de la segunda mitad then begin recargar la primera mitad; pasar delantero al principio de la primera mitad; else /* eof dentro de un buffer significa el final de la entrada */ terminar el análisis léxico; Lex1 lex eof lex3 lex4 eof eof Delantero Lexema_en_curso

12 Especificación de los componentes léxicos
Las expresiones regulares son una notación importante para especificar patrones. Cada patrón concuerda con una serie de cadenas, de modo que las expresiones regulares servirán como nombres para conjuntos de cadenas. Los temas relacionados con la especificación de componentes léxicos que se tratarán son: Cadenas y lenguajes Operaciones aplicadas a lenguajes Expresiones regulares Definiciones regulares Abreviaturas de notación

13 Cadenas y lenguajes Alfabeto o clase de carácter
Se utiliza para denotar cualquier conjunto finito de símbolos. Ejemplos: Letras y caracteres El conjunto {0,1} es el alfabeto binario Cadena sobre algún alfabeto Es una secuencia finita de símbolos tomados de ese alfabeto. Frase y palabra se utilizan como sinónimos de cadena La longitud de una cadena s (|s|) es el número de símbolos en ella. La cadena vacía tiene longitud 0. Lenguaje Se refiere a cualquier conjunto de cadenas de un alfabeto. Ejemplos El conjunto que solo tiene la cadena vacía {ε} El conjunto de todos los programas escritos en C.

14 Operaciones aplicadas a lenguajes
Unión de L y M Concatenación de L y M Cerradura de Kleene de L Cerradura positiva de L Ejemplos: L = {A, B, …, Z a, b, …, z} y D = {0, 1, …, 9} 1.- L U D es el conjunto de letras y dígitos 2.- LD es el conjunto de cadenas que consta de una letra seguida de un dígito 3.- L4 es el conjunto de todas las cadenas de cuatro letras 4.- L* es el conjunto de todas las cadenas, incluyendo la cadena vacía. 5.- L(L U D)* es el conjunto de todas las cadenas de letras y dígitos que comienzan con una letra. 6.- D+ es el conjunto de todas las cadenas de uno o más dígitos.

15 Expresiones regulares
Son una notación que permite definir de forma precisa conjuntos. Ej. Un identificador letra ( letra | dígito) * Una expresión regular se compone de un conjunto de reglas definitorias más simples. Las reglas que definen las expresiones regulares de un alfabeto Σ son: ε es una expresión regular designada por {ε}; es decir, el conjunto que contiene la cadena vacía. Si a es un símbolo de Σ, entonces a es una expresión regular designada por {a}. Suponiendo que r y s sean expresiones regularse representadas por los lenguajes L(r) y L(s), entonces: (r) | (s) es una expresión regular representada por L(r) U L(s) (r)(s) es una expresión regular representada por L(r)L(s) (r)* es una expresión regular representada por (L(r))* (r) es una es una expresión regular representada por L(r) Se dice que el lenguaje regular designado por una expresión regular es un conjunto regular.

16 Expresiones regulares (2)
Ejemplo Sea Σ = {a,b} a | b designa el conjunto {a, b} (a | b)(a | b) designa el conjunto {aa, ab, ba, bb} a* designa el conjunto {ε, a, aa, aaa, …} (a | b)* es equivalente a (a*b*)* Propiedades algebraicas de las expresiones regulares:

17 Definiciones regulares
Es común dar un nombre a una expresión regular, dicho nombre es usado como si fuera un símbolo de Σ. Si Σ es un alfabeto de símbolos básicos, entonces una definición regular es una secuencia de definiciones de la forma: d1 → r1 d2 → r2 . . . dn → rn Donde cada di es un nombre distinto, y cada ri es una expresión regular sobre los símbolos de Σ U {d1, d2, …, di-1}. Para distinguir el nombre de una expresión regular de los símbolos, se debe hacer una distinción al escribirlo (por ejemplo en negritas). Ejemplo: Dígito → 0 | 1 | … | 9 NumEp → Dígito Dígito*

18 Abreviaturas de notación
Convenientes para construcciones frecuentes en una expresión regular Uno o más casos Se utiliza el operador + Ejemplo: a+ representa el conjunto de todas las cadenas de una o más a. Cero o un caso Se utiliza el operador ? - ? Digito + representa cadenas que forman números enteros positivos y negativos. Clases de caracteres Se utiliza la notación [abc], donde a, b y c son símbolos de Σ. Ejemplos: [abc] representa uno de los caracteres a, b o c [a-z] representa cualquier letra minúscula del alfabeto

19 Reconocimiento de componentes léxicos
El objetivo es construir un analizador léxico que aísle el lexema para el siguiente token del buffer de entrada y que produzca como salida un par formado por el token y el valor del atributo correspondiente al lexema. Dicho de otra manera, el analizador léxico por cada token reconocido informa dos cosas: El tipo de token encontrado (ej. ID, NUMERO), y De cuál token en particular se trata (ej. el lexema [“varialbe”, 12] o un apuntador a la tabla de símbolos).

20 Diagramas de transiciones
Son un paso intermedio en la construcción de un analizador léxico. Representan las acciones que se realizan cuando el analizador léxico es llamado por el sintáctico. Se trata de AFD, donde los nodos son las posiciones, es decir, los estados, y las aristas están etiquetadas con un símbolo del lenguaje. 9 10 11 inicio letra / digito otro * Retorna (reservada, id)

21 Implantación de un diagrama de transiciones
A cada estado le corresponde un segmento de código. Si hay aristas que salen de un estado, entonces su código lee un caracter y selecciona una arista para seguir, si es posible. La implementación se puede realizar por medio de tablas (matrices indexadas por caracteres), o bien por medio de sentencias case. Ej. case switch (estado){ case 9: c = sigcar(); if( esletra(c)) estado = 10; … break; case 10: c = sigcar(); if(esletra(c)) estado = 10; else if(esdigito(c)) estado = 10; else estado = 11; case 11: regresa(1); return instalaid(); 9 10 11 inicio letra / digito otro * instalaid ();


Descargar ppt "Programación de sistemas"

Presentaciones similares


Anuncios Google