Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Función del analizador léxico (2) Función del analizador léxico (3)
• Un analizador léxico aísla al analizador sintáctico de • Interfaz con el analizador sintáctico
la representación en lexemas de los componentes • Es habitual que el analizador léxico y el sintáctico formen un par
léxicos. Tiene como funciones: productor-consumidor. El analizador léxico produce componentes léxicos
y el analizador sintáctico los consume.
– Eliminación de espacios en blanco y comentarios. Si el componente
analizador léxico elimina los espacios en blanco, el léxico
analizador sintáctico nunca tendrá que considerarlos. La programa Analizador Analizador
alternativa de modificar la gramática para incorporar los fuente léxico sintáctico
obtén sig.
espacios en blanco dentro de la situación no es tan fácil de comp. lex.
implantar.
Tabla de
– Reconocimiento de identificadores y palabras clave. Es símbolos
el encargado de construir los lexemas que constituyen los
identificadores de los lenguajes de programación. • Hay varias razones para dividir la fase de análisis de la compilación en
– Reconocimiento de constantes. La tarea de agrupar dígitos análisis léxico y análisis sintáctico.
para formar enteros se le asigna, por lo general, a un 1.Separar el análisis léxico del análisis sintáctico a menudo permite simplificar
analizador léxico, porque los números se pueden tratar una u otra de dichas fases.
como unidades simples durante la traducción. 2.Se mejora la eficiencia del compilador.
3.Se mejora la transportabilidad del compilador.
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 3 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 4
Función del analizador léxico (4) Función del analizador léxico (5)
• Atributos de los componentes léxicos Ejemplo.
• Cuando concuerda con un patrón más de un lexema, el
analizador léxico debe proporcionar información adicional printf("Resultado: %d\n", 25);
sobre el lexema concreto que concordó a las siguientes fases <id, apuntador a la entrada de la tabla de símbolos para printf >
del compilador. <(, >
• El analizador léxico recoge información sobre los <str, apuntador a la cadena "Resultado: %d\n">
componentes léxicos en sus atributos asociados. <,,>
• Los componentes léxicos influyen en las decisiones del <núm, valor entero 25 >
análisis sintáctico, y los atributos, en la traducción de los
< ),>
componentes léxicos. En la práctica, los componentes.
<;,>
• En la práctica, los componentes léxicos suelen tener un solo
atributo –un apuntador a la entrada de la tabla de símbolos
donde se guarda la información sobre el componente léxico.
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 5 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 6
Función del analizador léxico (6) Función del analizador léxico (7)
function analex: integer;
var buflex: array [0..100] of char; c: char;
• Errores léxicos begin
loop begin
• Son pocos los errores léxicos que se pueden detectar lee un carácter en c;
if c es un espacio o un tabulador then no hacer nada;
simplemente a nivel léxico porque un analizador else if c es un carácter de línea nueva then numlínea:=numlínea+1;
léxico tiene una visión muy restringida del programa else if c es un dígito then begin
asignar a valcomplex el valor de éste y los dígitos siguientes;
fuente. return NUM
• La estrategia de recuperación más sencilla es el end
else if c es una letra then begin
“modo pánico”. Se borran caracteres sucesivos de la poner c y las letras y dígitos sucesivos en buflex;
entrada hasta que el analizador léxico pueda encontrar p:=busca(buflex);
if p=0 then p:=inserta(buflex, ID);
un componente léxico bien formado. valcomplex:=p;
return el campo complex de la entrada p de la tabla
• Otras posibles acciones de recuperación son: end
1. Borrar un carácter extraño else begin
valcomplex:= NINGUNO;
2. Insertar un carácter que falta return el número entero del código del carácter c
3. Reemplazar un carácter incorrecto por otro correcto end
end
4. Intercambiar dos caracteres adyacentes. end
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 7 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 8
Manejo de buffers de entrada (1) Manejo de buffers de entrada (2)
• Se utiliza un buffer dividido en dos mitades de N caracteres cada una.
• Existen tres métodos generales de implantación de un analizador E = M * C * * 2 eof
léxico:
–Utilizar un generador de analizadores léxicos delantero
–Escribir el analizador léxico en un lenguaje convencional de comienzo_lexema
programación de sistemas
• Se leen N caracteres en cada mitad del buffer con una orden de lectura de
–Escribir el analizador léxico en lenguaje ensamblador
sistema, en vez de invocar una instrucción de lectura para cada carácter.
• Estos enfoques tienen un orden de dificultad creciente,
lamentablemente los enfoques más difíciles consiguen analizadores Si quedan menos de N caracteres en la entrada, entonces se lee un
léxicos más rápidos. carácter especial eof en el buffer después de los caracteres de entrada.
• Como el analizador léxico es la única fase que lee el programa carácter • Se mantienen dos apuntadores al buffer de entrada. La cadena de
a carácter su velocidad es un problema en el diseño de compiladores. caracteres entre los dos apuntadores es el lexema en curso. Al principio,
• Además en muchos lenguajes el analizador léxico necesita preanalizar los dos apuntadores apuntan al primer carácter del próximo lexema que
varios caracteres, antes de poder anunciar una concordancia. Los
caracteres preanalizados se tienen que devolver después a la entrada. hay que encontrar.
Como se puede consumir mucho tiempo moviendo caracteres, se han • El apuntador delantero, examina hacia delante hasta encontrar una
desarrollado técnicas especializadas en el manejo de buffers para concordancia con un patrón. Una vez determinado el siguiente lexema, el
reducir el número de operaciones necesarias para procesar un carácter
de entrada. apuntador delantero se coloca en el carácter de su extremo derecho.
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 9 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 10
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 13 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 14
–F
F ⊂ Q es el conjunto de estados finales o estados (q2) q3 q3 q3 q2 q3
estados = nodos a, b, c
de aceptación (q3) q3 q2 q2
transiciones = arcos
estados finales = nodo con doble circulo
estado inicial = nodo con flecha de entrada
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 23 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 24
Autómatas finitos (4) Autómatas finitos ~
(5)
cerr-εε(q) = {f (q, εn)}∪{q}.
Es decir el conjunto de estados a los que puedo
• Simulación de un AFD llegar a partir del estado q mediante transiciones ε (sin consumir entrada)
cerr-εε(T)= ∪q∈T cerr-ε(q)
s := s0;
mueve (s,c) es una función que • Paso de un AFND a un AFD
c := sgtecar(); implementa la función de • Algoritmo: Construcción de subconjuntos
while c ≠ eof do
transición, dado un estado y un
carácter nos devuelve el estado estaD← cerr-ε(q0);
siguiente.
begin while haya un estado T sin marcar en estaD do
sgtecar ( ) es una función que marcar T;
s := mueve(s,c); accede al siguiente carácter de la
cadena de entrada. for cada símbolo de entrada a∈Σ do
c := sgtecar(); U := cerr-ε(mueve(T, a));
dnd; if U∉estaD then añadir U sin marcar a estaD
if s∈F then return “SI” else return “NO” tranD[T, a] := U
AFND( Σ,Q, f, q0, F ) →AFD( Σ,estaD, tranD, cerr-ε(q0), F ) F={U∈estaD: U∩F ≠ ∅}
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 25 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 26
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 27 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 28
Paso de una expresión regular a un Construcción de un AFD a partir
AFN (3) de una expresión regular (1)
• Simulación de un AFND • Construirla e.r. ampliada α$ $∉Σ
S :=cerr-ε({s0 }); • Obtener el árbol sintáctico de α$
mueve (S,c) función de transición,
dado un cjto de estados y un carácter • Responder a las preguntas:
c := sgtecar(); nos devuelve los estados siguientes. –¿Que letras pueden aparecer como primera letra de la e.r.
while c ≠ eof do sgtecar ( ) accede al siguiente representada por α cuáles como últimas?
carácter de la entrada. –¿Supuesto que yo se que letra acaba de aparecer, que letras
begin
cerr-εε (S) conjunto de estados a los pueden venir a continuación en las palabras representadas
S := cerr-ε(mueve(S,c)); que se puede llegar a partiendo de por α?
estados de S y siguiendo arcos
c := sgtecar(); etiquetados con ε.
–La idea es tratar de numerar la posición de las letras que
aparecen en la e.r. Una vez que tengo el árbol puedo hacer
end una numeración, lo cual me da una ordenación parcial. Se
establece una equivalencia entre los estados significativos
if S∩F≠∅ then return “SI” else return “NO” del autómata y las posiciones del árbol (nodos hoja).
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 29 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 30
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 31 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 32
Construcción de un AFD a partir Construcción de un AFD a partir
de una expresión regular (4) de una expresión regular (5)
• Cálculo de las funciones: anulable, primera-pos y última-pos • La función siguiente-pos(i) indica qué posiciones
Nodo anulable(n) primera-pos(n) última-pos(n) pueden seguir a la posición i en el árbol sintáctico. Dos
n es una hoja
true ∅ ∅ reglas definen todas las formas en que una posición
con símbolo ε
n es una hoja
puede seguir a otra:
con la posición i false {i} {i} –Si n es un nodo-cat con hijo izquierdo c1 e hijo derecho c2, e i
n |
es una posición dentro de última-pos(c1), entonces todas las
∨anul(c2) pripos(c1)∪pripos(c2) últpos(c1)∪últpos(c2)
anul(c1)∨ posiciones de primera-pos(c2) están en siguiente-pos(i).
c1 c2
∀i∈última-pos(c1) siguiente-pos(i) ⊃ primera-pos(c2)
if anul(c1) then if anul(c2) then
n · ∧anul(c2) pripos(c1)∪pripos(c2) últpos(c1)∪últpos(c2)
anul(c1)∧ –Si n es un nodo-ast, e i es una posición dentro de última-
c1 c2 else pripos(c1) else últpos(c2) pos(n), entonces todas las posiciones de primera-pos(n) están
en siguiente-pos(i)
n *
true pripos(c1) últpos(c1) ∀i∈última-pos(c1) siguiente-pos(i) ⊃ primera-pos(c1)
c1
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 33 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 34
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 35 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 36
Diseño de un generador de Diseño de un generador de
analizadores léxicos (1) analizadores léxicos (2)
• Supóngase que se tiene una especificación de un • Un método es construir la tabla de transiciones de un
analizador léxico de la forma: autómata finito no determinista N para el patrón
p1 {acción1} pi es una expresión regular
compuesto p1|p2| ... | pn. Esto se puede hacer creando
p2 {acción2} accióni es un fragmento de programa que debe ejecutarse
primero un AFND N(pi) para cada patrón pi
... siempre que se encuentre en la entrada un lexema que
concuerde con pi
utilizando el algoritmo de Thompson, añadiendo
pn {acciónn} después un nuevo estado de inicio s0, y por último
enlazando s0 al estado de inicio de cada N(pi) con una
• El problema es construir un reconocedor que busque transición ε.
lexemas en el buffer de la entrada. Si concuerda más ε N(p1)
de un patrón, el reconocedor elegirá el lexema más
largo que haya concordado. Si hay dos o más
patrones que concuerden con el lexema más largo, se s0
ε N(p2)
elige el primer patrón que haya concordado de la ...
lista. ε
N(pn)
César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 37 César Ignacio García Osorio. Universidad de Burgos. PL. Análisis léxico. 38
Diseño de un generador de
analizadores léxicos (3)
• Cuando se simula el AFND, se construye la secuencia de conjuntos de estados
donde puede estar el AFND combinado después de leer cada carácter de
entrada.
• Siempre que se añada un estado de aceptación al conjunto de estados en curso,
se registran la posición del puntero delantero y el patrón pi correspondiente a
este estado de aceptación. Si el conjunto de estados en curso ya contiene un
estado de aceptación, entonces solo se registra el patrón que aparezca primero
en la especificación de LEX.
• Incluso si se encuentra un conjunto de estado que contenga un estado de
aceptación, para encontrar la concordancia más larga se debe seguir simulando
el AFND hasta alcanzar terminación, es decir, un conjunto de estados desde el
que no hay transiciones con el símbolo de entrada en curso.
• En la terminación se retrocede el apuntador delantero a la posición en que
ocurrió la última concordancia. El patrón que hizo dicha concordancia
identifica al componente léxico encontrado, y el lexema emparejado es la
cadena entre los apuntadores de inicio del lexema y delantero. (además existe
un patrón de error)