Anda di halaman 1dari 11

INSTITUTO TECNOLOGICO DE POCHUTLA

MATERIA: LENGUAJES Y AUTOMATAS 1.

NOMBRE DEL MAESTRO: SALINAS SANCHEZ ALBERTO.

INTEGRANTES DEL EQUIPO:


OLIVER CANSECO VÁZQUEZ.
ABELARDO GUTIERREZ LÓPEZ.
OLIVER PÉREZ CARMONA.
DANIEL RAMÍREZ MARTÍNEZ.
GIANLUCA DE JESUS PACHECO GARCÍA.

CARRERA: INGENIERIA EN SISTEMAS COMPUTACIONALES.

TRABAJO: INVESTIGACIÓN UNIDAD 4.

SEMESTRE: 6.

FECHA DE ENTREGA: 8/04/2019.


ANÁLISIS LÉXICO
El analizador léxico es la primera fase de un compilador. Su principal función consiste en
leer los caracteres de entrada y elaborar como salida una secuencia de componentes léxicos
que utiliza el analizador sintáctico para hacer el análisis. Como el analizador léxico es la parte
del compilador que lee el texto fuente, también puede realizar ciertas funciones secundarias
en la interfaz del usuario, como eliminar del programa fuente comentarios y espacios en
blanco en forma de caracteres de espacio en blanco, caracteres TAB y de línea nueva. Otra
función es relacionar los mensajes de error del compilador con el programa fuente. En
algunas ocasiones, los analizadores léxicos se dividen en una cascada de dos fases; la
primera, llamada "examen", y la segunda, "análisis léxico". El examinador se encarga de
realizar tares sencillas, mientras que el analizador léxico es el que realiza las operaciones
complejas.

4.1. FUNCIONES DEL ANALIZADOR LÉXICO


Analizador léxico (scanner): lee la secuencia de caracteres del programa fuente, carácter a
carácter, y los agrupa para formar unidades con significado propio, los componentes léxicos
(tokens en inglés). Estos componentes léxicos representan:

 Palabras reservadas: if, while, do, . . .


 Identificadores: asociados a variables, nombres de funciones, tipos definidos por el
usuario, etiquetas, ... Por ejemplo: posición, velocidad, tiempo, . . .
 Operadores: = * + - / == > < &! = . . .
 Símbolos especiales: ( ) [ ] { } ...
 Constantes numéricas: literales que representan valores enteros, en coma flotante, etc.,
982, 0xF678, -83.2E+2, ...
 Constantes de caracteres: literales que representan cadenas concretas de caracteres, “hola
mundo”, ...
El analizador léxico opera bajo petición del analizador sintáctico devolviendo un componente
léxico conforme el analizador sintáctico lo va necesitando para avanzar en la gramática. Los
componentes léxicos son los símbolos terminales de la gramática. Suele implementarse como
una subrutina del analizador sintáctico. Cuando recibe la orden obtiene el siguiente
componente léxico, el analizador léxico lee los caracteres de entrada hasta identificar el
siguiente componente léxico.

Otras funciones secundarias:

 Manejo del fichero de entrada del programa fuente: abrirlo, leer sus caracteres, cerrarlo y
gestionar posibles errores de lectura.
 Eliminar comentarios, espacios en blanco, tabuladores y saltos de línea (caracteres no
válidos para formar un token).
 Inclusión de ficheros: # include ...
 La expansión de macros y funciones inline: # define ...
 Contabilizar el número de líneas y columnas para emitir mensajes de error.
 Reconocimiento y ejecución de las directivas de compilación (por ejemplo, para depurar
u optimizar el código fuente).

Ventajas de separar el análisis léxico y el análisis sintáctico:

 Facilita transportabilidad del traductor (por ejemplo, si decidimos en un momento dado


cambiar las palabras reservadas begin y end de inicio y fin de bloque, por {y}, sólo hay
que cambiar este módulo.
 Se simplifica el diseño: el analizador es un objeto con el que se interactúa mediante ciertos
métodos. Se localiza en un ´único módulo la lectura física de los caracteres, por lo que
facilita tratamientos especializados de E/S.

4.2 COMPONENTES LÉXICOS, PATRONES Y LEXEMAS

Patrón: es una regla que genera la secuencia de caracteres que puede representar a un
determinado componente léxico (una expresión regular). Lexema: cadena de caracteres que
concuerda con un patrón que describe un componente léxico. Un componente léxico puede
tener uno o infinitos lexemas. Por ejemplo: palabras reservadas tienen un ´único lexema. Los
números y los identificadores tienen infinitos lexemas.

Los componentes léxicos se suelen definir como un tipo enumerado. Se codifican como
enteros. También se suele almacenar la cadena de caracteres que se acaba de reconocer (el
lexema), que se usara posteriormente para el análisis semántico.

typedef enum {TKN_IF, TKN_THEN, TKN_NUM, TKN_ID, TKN_OPADD,} TokenType;

Es importante conocer el lexema (para construir la tabla de símbolos). Los componentes


léxicos se representan mediante una estructura registro con tipo de token y lexema:

typedef struct {

TokenType token;

char *lexema; //se reserva memoria dinámicamente


} TokenRecord;

TokenRecord getToken(void);

Cada componente léxico va acompañado de su lexema:

<TKN ID, a>

<TKN CORAPER, [>

<TKN ID, índice>

<TKN CORCIERRE,]>

<TKN NUM, 2>

<TKN OPADD, +>

<TKN NUM, 4>

4.3 CREACIÓN DE TABLA DE TOKENS


La tabla de símbolos es una estructura de datos muy importante en casi todo el proceso de
compilación. En ella se guarda durante las primeras fases de compilación los nombres de los
identificadores (símbolos) usados en el programa fuente, además de los atributos de cada uno
de estos identificadores. Estos identificadores y símbolos junto con sus atributos serán usados
posteriormente para realizar funciones como el chequeo de tipos, la asignación de memoria,
generación de código objeto etc.

Un compilador necesita guardar y usar la información de los objetos que se va encontrando


en el texto fuente, como variables, etiquetas, declaraciones de tipos, etc. Esta información se
almacena en una estructura de datos interna conocida como tabla de símbolos.
TABLA DE SIMBOLOS

Contenido de la tabla de símbolos:


 Identificadores.
 Tipos de datos.
 Palabras reservadas.
 Sentencias o instrucciones.
 Comentarios.
 Expresiones.
 Operaciones.

Esencialmente la información que aparece en la tabla de símbolos es de dos tipos:


 El propio símbolo.
 Los atributos necesarios para definir el símbolo a nivel semántico y de generación de
código.

Operaciones sobre la tabla de símbolos.

 INSERTAR.
 CONSULTAR.
 MODIFICAR (añadir atributos nuevos).
El CUANDO y el CÓMO se usan estas operaciones dependen del tipo de lenguaje:

Lenguajes con declaraciones de variables:


 Explícitas:
* Declaraciones: sólo INSERTAR.
* Referencia: sólo CONSULTAR.

 Implícitas:
* CONSULTAR si no está ya incluida.
* INSERTAR, en caso contrario.
* Lenguajes con estructura de BLOQUE: CREAR SUBTABLAS

 Operadores relacionales: <, <=, >, >=, == y !=.

 Operadores de operaciones con bits:


<< Corrimiento a la izquierda.
>> Corrimiento a la derecha.
& And
| Or
^ Xor

 Operadores Lógicos:
&& And
|| Or
! Not

 OPERADORES DE ASIGNACIÓN
= Asignación.
*= Asignación de producto.
/= Asignación de cociente.
%= Asignación de residuo.
+= Asignación de suma.
-= Asignación de diferencia.
<<= Asignación de corrimiento a la izquierda.
>>= Asignación de corrimiento a la derecha.
&= Asignación de And de bits.
^= Asignación de Xor de bits.
|= Asignación de Or de bits.

 OPERADORES DE PERTENENCIA A CLASES

:: Resolución de área de visualización de clases.


.y* Apuntadores de referencia de un apuntador a un miembro de una clase.
-> y * Apuntadores de referencia a apuntadores de un miembro de una clase.

4.4 ERRORES LÉXICOS


Los errores léxicos se detectan cuando el analizador léxico intenta reconocer componentes
léxicos y la cadena de caracteres de la entrada no encaja con ningún patrón. Son situaciones
en las que usa un carácter invalido (@, $,”,¿,...), que no pertenece al vocabulario del lenguaje
de programación, al escribir mal un identificador, palabra reservada u operador. Errores
léxicos típicos son:

1. Nombres ilegales de identificadores: un nombre contiene caracteres inválidos.

2. Números incorrectos: un número contiene caracteres inválidos o no está formado


correctamente, por ejemplo 3,14 en vez de 3.14 ´o 0.3.14.

3. Errores de ortografía en palabras reservadas: caracteres omitidos, adicionales o


cambiados de sitio, por ejemplo, la palabra hwile en vez de while.

4. Fin de archivo: se detecta un fin de archivo a la mitad de un componente léxico.

Los errores léxicos se deben a descuidos del programador. En general, la recuperación de


errores léxicos es sencilla y siempre se traduce en la generación de un error de sintaxis que
ser ‘ha detectado más tarde por el analizador sintáctico cuando el analizador léxico devuelve
un componente léxico que el analizador sintáctico no espera en esa posición.

Los métodos de recuperación de errores léxicos se basan bien en saltarse caracteres en la


entrada hasta que un patrón se ha podido reconocer; o bien usar otros métodos más
sofisticados que incluyen la inserción, borrado, sustitución de un carácter en la entrada o
intercambio de dos caracteres consecutivos. Una buena estrategia para la recuperación de
errores léxicos:

 Si en el momento de detectar el error ya hemos pasado por algún estado final ejecutamos
la acción correspondiente al ´ultimo estado final visitado con el lexema formado hasta
que salimos de ´el; el resto de los caracteres le ‘idos se devuelven al flujo de entrada y se
vuelve al estado inicial;
 Si no hemos pasado por ningún estado final, advertimos que el carácter encontrado no se
esperaba, lo eliminamos y proseguimos con el análisis.

4.5 GENERADORES DE ANALIZADORES LÉXICOS

Existen varias herramientas para el tratamiento masivo de la información contenida en


ficheros de texto, que nos permiten traducir el lenguaje contenido en el código fuente a un
lenguaje fácil de comprender para el próximo analizador: el sintáctico, todos estos análisis
se van elaborando paso a paso
dentro de la ‘línea’.
Todas ellas se apoyan en las expresiones regulares para llevar a cabo su cometido, y permiten
encadenar su salida a modo de tubería con otras herramientas, para que de esta forma se
aumentase su potencia de procesamiento. Pero a menudo todo esto no es suficiente. En
ocasiones se requiere poder realizar acciones de más alto nivel o bien mucho más complejas
en cada ocurrencia de una expresión regular. El corazón del generador del analizador léxico
es su algoritmo para producir una máquina de estados finitos El algoritmo que se presenta
está basado en un método para generar un autómata finito determinístico (AFD) de estados
mínimos. Los generadores de analizadores léxicos son:

 Lex: Código generado: C.


 Flex: Código generado: C++.
 Zlex: Código generado: C.
 Jax: Código generado: Java. No soporta entornos, está basado en expresiones regulares.
No soporta Unicode.
 Jlex: Código generado: Java. Similar a lex.

Hablaremos de los analizadores más comúnmente empleados: Lex y Flex

LEX

Lex es una herramienta de los sistemas UNIX/Linux que nos va a permitir generar código C
que luego podremos compilar y enlazar con nuestro programa. La principal característica
de Lex es que nos va a permitir asociar acciones descritas en C, a la localización de las
Expresiones Regulares que le hayamos definido. Para ello Lex se apoya en una plantilla que
recibe como parámetro, y que deberemos diseñar con cuidado.

Internamente Lex va a actuar como un autómata que localizará las expresiones regulares que
le describamos, y una vez reconocida la cadena representada por dicha expresión regular,
ejecutará el código asociado a esa regla.

Lex va a permitirnos definir nuestras propias acciones en un lenguaje mucho más común: C.
La plantilla en la que Lex se va a apoyar para generar el código C, y donde nosotros
deberemos describir toda la funcionalidad requerida, va a ser un fichero de texto plano con
una estructura bien definida, donde iremos describiendo las expresiones regulares y las
acciones asociadas a ella. Se compone de tres secciones con estructuras distintas y claramente
delimitadas por una línea en la que lo único que aparece es el carácter doble %. Las secciones
de ‘Declaraciones’ y la de ‘Procedimientos de Usuario’ son opcionales, mientras que la de
‘Reglas’ es obligatoria (aunque se encuentre vacía).

FLEX

Flex es una herramienta que traduce la especificación de un analizador léxico a un programa


escrito en C que lo implementa. Para especificarlo usaremos expresiones regulares a las que
se puede asociar acciones escritas en C. Cada vez que el analizador encuentra en la cadena
de entrada una secuencia que encaja en una de las expresiones regulares especificadas,
ejecutará la acción que le hallamos asociado.

Funcionamiento del analizador:

El fichero Flex contiene las tablas de autómata generado y la función int flex(void) que simula
el analizador especificado y sirve de interfaz con el código de usuario (flex () deberá de ser
llamada en algún punto del código del usuario)

En cada llamada, flex () irá tomando caracteres de la entrada hasta que machee una de las
expresiones regulares de la especificación. Entonces, se almacenará el texto que ha macheado
la expresión. reg. en la variable text y se ejecutarán las acciones asociadas al patrón.

Las acciones podrán ser simplemente el procesamiento del texto macheado y enviarlo de
nuevo a la salida.

En otras ocasiones podrán suponer la alteración de variables del código de usuario y la


devolución a la rutina que llama flex () de algún tipo de dato por medio de RETURN
(generalmente será un valor numérico que identifique la TOKEN encontrado).

4.6 APLICACIONES (CASO DE ESTUDIO)


Además de para construir compiladores e intérpretes, los analizadores léxicos se pueden
emplear para muchos programas \convencionales”. Los ejemplos más claros son aquellos
programas que tienen algún tipo de entrada de texto donde hay un formato razonablemente
libre en cuantos espacios y comentarios. En estos casos es bastante engorroso controlar donde
empieza y termina cada componente y es fácil liarse con los punteros a char. Un analizador
léxico simplifica notablemente la interfaz y si se dispone de un generador automático, el
problema se resuelve en pocas líneas de código.

Anda mungkin juga menyukai