Análisis léxico
Edgardo A. Franco
Instituto Politécnico Nacional, México
[Link]
Introducción
Para la construcción de todo traductor, compilador o interprete, es
necesario analizar el texto de entrada de manera eficiente.
En el ámbito de compiladores, el análisis léxico es la parte que tiene
contacto directo con el código fuente, el analizador léxico hace las
funciones, a la vez, de preprocesador y de scanner o lexer.
Análisis léxico
● La función principal del analizador léxico 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.
● Esta interacción, suele aplicarse convirtiendo al analizador léxico en
una subrutina o corrutina del analizador sintáctico.
○ Recibida la orden “Dame el siguiente componente léxico” del analizador
sintáctico, el analizador léxico lee los caracteres de entrada hasta que pueda
identificar el siguiente componente léxico.
Análisis Léxico
Interacciones entre el analizador léxico y el analizador sintáctico
Funciones del analizador léxico
● Eliminar o saltar comentarios, espacios en blanco, tabuladores, retorno de carro, ...,
y en general, todo aquello que carezca de significado según la sintaxis del lenguaje.
(Preprocesamiento).
● Reconocer los tokens: identificadores del usuario, números, palabras reservadas
del lenguaje, ..., y tratarlos correctamente con respecto a la tabla de símbolos (sólo
en los casos que debe de tratar con la tabla de símbolos).
Para reconocer el token usa un patrón o regla que describe cómo se forman las cadenas
que corresponden a un token.
Funciones del analizador léxico
● Llevar la cuenta del número de línea por la que va leyendo, por
si se produce algún error, dar información sobre dónde se ha
producido.
● Avisar de errores léxicos. P.g., si @ no pertenece al lenguaje,
avisar de un error, es posible que recupere el error. *No se
encuentre el patrón
● Puede hacer funciones de preprocesador.
○ P.g. Convertir los valores literales al tipo que corresponda.
Tokens y lexemas
● Token:
○ Elemento básico del lenguaje
○ Unidad léxica indivisible
○ Identifica una entidad lógica dentro del lenguaje
○ Incluyen: Palabras Reservadas, Constantes, Operadores, Signos de Puntuación e Identificadores
● Lexema:
○ La cadena original que se identifica como token
○ No hay correspondencia 1-1 entre token-lexema
Tokens y lexemas
Palabras Reservadas
● Una palabra reservada es aquella que inicia con una letra, y es
seguida por letras o dígitos.
● Las palabras clave cumplen con este mismo patrón de construcción
por lo tanto.
○ Se hace necesario un mecanismo que permita decidir cuando una cadena es
una palabra clave o un identificador
■ Solución sencilla: Las palabras reservadas no pueden ser usadas como
identificadores.
Estrategias de recuperación de errores léxicos
● Modo Pánico: obvia los siguientes caracteres de la entrada hasta
encontrar un token bien formado.
● Tratar de Arreglar la entrada:
○ Borrar el carácter extraño
○ Insertar el carácter perdido
○ Reemplazar un carácter incorrecto por uno correcto
○ Encontrar que cambio genera el menor número de errores sintácticos, y
aplicarlo
Manejo de búferes
● El manejo de búferes tiene la intención de mejorar el rendimiento de
esta primera fase donde se hace necesario el acceso al archivo con el
código fuente de entrada.
● El estar continuamente accediendo a llamadas del sistema que operan
con archivos, no siempre es eficiente.
● Es bien conocido que el realizar una transferencia previa de la
información de un archivo a memoria, permitirá obtener una mayor
eficiencia a la hora de procesar dicha información.
Manejo de búferes
● Cuando se implementa analizador léxico se hace necesario manejar un
búfer de entrada para hacer más eficiente la lectura de la cadena de
entrada y así evitar la sobrecarga requerida en el procesamiento de un solo
carácter de entrada.
Manejo de búferes
● Generalmente se define un búfer del tamaño de un bloque de disco (4096 bytes).
● Se maneja un apuntador que marca el inicio del lexema que se está analizando, y
un apuntador que marca el carácter que está siendo analizado.
Manejo de búferes
● Existen ocasiones en que es necesario buscar uno o más
caracteres más allá del siguiente lexema para poder estar
seguros de que tenemos el lexema correcto.
○ P.g. en C los caracteres -, = o < podrán ser un operador o el
principio de otros ->, == o <=.
Manejo de búferes
● Posibilidades
○ Un búfer
○ Par de búferes
Manejo de búferes
Centinelas
● Es un carácter especial que no puede formar parte del programa fuente. (P.g. EOF).
● Entonces EOF significa:
○ Se llegó al final del 1er búfer y debe ser cargado el segundo.
○ Se llegó al final del 2do búfer y debe ser cargado el primero
○ Se llegó al final del archivo
Implementación del algoritmo
● Se construyen dos buffers, cada búfer de tamaño N, por lo general de un bloque
de disco (4096 bytes).
● Mediante un comando de lectura del sistema podemos leer N caracteres y
colocarlos en el buffer, en vez de utilizar una llamada al sistema por cada carácter.
● Si quedan menos de N caracteres en el archivo de entrada, entonces se coloca un
EOF, marcando el final del archivo fuente.
○ Se mantienen dos apuntadores a la entrada:
■ El apuntador inicioLexema marca el inicio del lexema actual, cuya extensión se está tratando
de determinar.
■ El apuntador avance explora por adelantado hasta encontrar una coincidencia en el patrón.
Implementación del algoritmo
● Una vez que se determina el siguiente lexema, avance se coloca
en el carácter que se encuentra en su extremo derecho.
● Después una vez que el lexema se registra como un valor de
atributo de un token devuelto al analizador sintáctico,
inicioLexema se coloca en el carácter que va justo después del
lexema que acabamos de encontrar.
Implementación del algoritmo
● Para desplazar avance hacia adelante primero tenemos que probar si
hemos llegado al final de uno de los dos búferes, y de ser así, debemos
recargar el otro búfer de la entrada, y mover avance al principio del
búfer recién cargado.
● Siempre y cuando no tengamos que alejarnos tanto del lexema como
para que la suma de su longitud más la distancia que nos alejamos sea
mayor que N (Evitar sobrescribir el lexema en su búfer antes de poder
determinarlo).