100 ANALISIS LEXICO
ses de caracteres, se puede definir los identificadores como cadenas generadas
por la expresion regular
[A-2Za-z] [A-Za-20-9]*
Conjuntos no regulares
Algunos lenguajes no se pueden describir con ninguna expresién regular. Para ilus-
trar los limites del poder descriptivo de las expresiones regulares, se dan a continua-
cién ejemplos de construcciones de lenguajes de programacién que no se pueden
describir con expresiones regulares. En las referencias estan las pruebas de tales afir-
maciones.
No se pueden utilizar las expresiones regulares para describir construcciones
equilibradas 0 anidadas. Por ejemplo, el conjunto de todas las cadenas de paréntesis
equilibrados no se puede describir con una expresién regular. Por otra parte, este
conjunto se puede especificar mediante una gramatica independiente del contexto.
Las cadenas de repeticién no se pueden describir con expresiones regulares. El
conjunto
ow | wes una cadena de simbolos a y b }
no se puede representar con ninguna expresiOn regular, ni se puede describir con
una gramatica independiente del contexto.
Las expresiones regulares se pueden utilizar para designar sélo un numero fijo
de repeticiones o un numero no especificado de repeticiones de una determinada
construccién. No se pueden comparar dos mimeros arbitrarios para comprobar si
son iguales. Por tanto, las cadenas Hollerith de la forma na a2 . . . d,, pertenecien-
tes a las primeras versiones de FORTRAN, no se pueden describir con una expre-
sién regular, pues el ntimero de caracteres que sigue a H debe concordar con el nu-
mero decimal m que precede a H.
3.4 RECONOCIMIENTO DE COMPONENTES LEXICOS
En la seccion anterior, se traté el problema de como especificar los componentes
lexicos. En esta seccién, se estudia el reconocimiento de los componentes léxicos y
se utiliza como ejemplo el lenguaje generado por la siguiente gramatica,
Ejemplo 3.6. Considérese el siguiente fragmento gramatical:
prop — if expr then prop
| if expr then prop else prop
Je
expr — término oprel término
| término
término > id
| adm3.4 RECONOCIMIENTO DE COMPONENTES LEXICOS 101
donde los terminales if, then, else, oprel, id y mim generan conjuntos de cadenas
dados por las siguientes definiciones regulares:
if>it
then — then
else > else
oprels< [ce l=]o [>|
id — letra ( letra | digito )*
nim —> digito"(. digito”)? (E(+ | — )? digito” )?
donde letra y digito se han definido anteriormente.
Para este fragmento de lenguaje, el analizador léxico reconocera las palabras clave
if, then, else. al igual que los lexemas representados por oprel, id y mim. Para
simplificar las cosas, se supone que las palabras clave son reservadas; es decir, no se
pueden usar como identificadores. Como en el ejemplo 3.5, mim representa los nu-
meros enteros y reales sin signo de Pascal.
Ademis, se supone que los lexemas estan separados por espacio en blanco, for-
mados por secuencias no nulas de espacios en blanco, caracteres TAB y caracteres
de nueva linea. El analizador léxico eliminara los espacios en blanco. Esto lo hara
comparando una cadena con la definicion de la expresion regular eb siguiente.
delim — blanco | tab | Iineanueva
eb — delim”
Si se encuentra una concordancia para eb, el analizador léxico no devuelve un com-
ponente léxico al analizador sintactico, sino que se dispone a encontrar un compo-
nente léxico a continuacién del espacio en blanco y lo devuelve al analizador sintac-
tico.
El objetivo es construir un analizador léxico que aisle el lexema para el siguiente
componente léxico del buffer de entrada y que produzca como salida un par for-
is PRESTON GOMTONENTE VALOR DEL ATRIBUTO
eb - si
if if =
then then =
else else -
id id apuntador a la entrada en la tabla
nim nim apuntador a la entrada en la tabla
< oprel MEN
« oprel MET
= oprel IGU
° oprel DIF
oprel MAY
oprel MAI
Fig. 3.10, Patrones de expresiones regulares para componentes léxicos.102 ANALISIS LEXICO
mado por el componente léxico apropiado y el valor de atributo, utilizando la tabla
de traduccion de la figura 3.10. Los valores de atributo para los operadores relacio-
nales estan dados por las constantes simbdlicas MEN, MEI, IGU, MAY, MAT. Qo
Diagramas de transiciones
Como paso intermedio en la construccién de un analizador Iéxico, primero se pro-
duce un diagrama de flujo estilizado, llamado diagrama de transiciones, Los diagra-
mas de transiciones representan las acciones que tienen lugar cuando el analizador
téxico es llamado por el analizador sintactico para obtener el siguiente componente
lexico, como sugiere la figura 3.1, Supdngase que el buffer de entrada es como el de
la figura 3.3 y que el apuntador del principio del lexema apunta al cardcter que sigue
al ultimo lexema encontrado. Se utiliza un diagrama de transicidn para localizar la
informacidn sobre los caracteres que se detectan a medida que el apuntador delan-
tero examina la entrada. Esto se hace cambiando de posicién en el diagrama segin
se leen los caracteres.
Las posiciones en un diagrama de transicién se representan con un circulo y se
Ilaman estados. Los estados se conectan mediante flechas, Ilamadas aristas. Las aris-
tas que salen del estado s tienen etiquetas que indican los caracteres de entrada que
pueden aparecer después de haber Ilegado el diagrama de transici6n al estado s. La
etiqueta otro se refiere a todo caracter que no haya sido indicado por ninguna de las
otras aristas que salen de s.
Se supone que los diagramas de transiciones de esta seccién son deterministas;
es decir, ningtin simbolo puede concordar con las etiquetas de dos aristas que salgan
de un estado. Al empezar la seccién 3.5, se hard menos rigurosa esta condicién, fa-
cilitando las cosas al diseftador del analizador léxico y, con las herramientas adecua-
das, también al encargado de su implantacién.
Un estado se etiqueta como el estado de inicio; es en el estado inicial del dia-
grama de transicién donde reside el control cuando se empieza a reconocer un com-
ponente léxico, Ciertos estados pueden tener acciones que se ejecutan cuando el flujo
del control alcanza dicho estado. Al entrar en un estado se Ice el siguiente caracter
de entrada. Si hay una arista del estado en curso de ejecucién cuya etiqueta con-
cuerde con ese caracter de entrada, entonces se va al estado apuntado por la arista.
De otro modo, se indica un fallo.
En la figura 3.11 se muestra un diagrama de transiciones para los patrones >= y
>. El diagrama de transiciones funciona de la siguiente forma. Su estado de inicio es
el estado 0. Enel estado 0 se lee el siguiente caracter de entrada. La arista etiquetada
con > del estado 0 se debe seguir hasta el estado 6 si este caracter de entrada es >. De
otro modo, significa que no se habra reconocido ni > ni >=.
Fig. 3.11. Diagrama de transiciones para3.4 RECONOCIMIENTO DE COMPONENTES LEXICOS 103
Al llegar al estado 6 se lee el siguiente caracter de entrada. La arista etiquetada
con = que sale del estado 6 deberd seguirse hasta el estado 7 si este cardcter de en-
trada es un =. De otro modo, la arista etiquetada con otro indica que se debera ir al
estado 8. El circulo doble del estado 7 indica que éste es un estado de aceptacion,
un estado en el cual se ha encontrado el componente léxico >=,
Obsérvese que el cardcter > y otro caracter adicional se leen a medida que se
sigue la secuencia de aristas desde el estado inicial al estado de aceptacion 8, Como
el cardcter adicional no es parte del operador relacional >, se debe retroceder un ca-
récter el apuntador delantero. Se usa un * para indicar los estados en que se debe
llevar a cabo este retroceso en la entrada.
En general, puede haber varios diagramas de transiciones, cada uno de los cuales
especifique un grupo de componentes léxicos. Si surge un fallo mientras se esta si-
guiendo un diagrama de transiciones, se debe retroceder el apuntador delantero hasta
donde estaba en el estado inicial de dicho diagrama, y activar el siguiente diagrama
de transiciones. Dado que los apuntadores de inicio de lexema y los delanteros mar-
caban la misma posicién en el estado inicial del diagrama, se retrocede el apuntador
delantero hasta la posicion que marca el apuntador al inicio de lexema. Si el fallo
surge en todos los diagramas de transiciones, es que se ha detectado un error léxico
y se invoca una rutina de recuperacion de errores,
Ejemplo 3.7. En la figura 3.12 se muestra un diagrama de transiciones para el com-
ponente léxico oprel. Obsérvese que la figura 3.11 es una parte de este diagrama de
transicion mas complejo. c
inicio
devuelve(opre!, MET)
devuelve(oprel, DIF)
devuelve(oprel, MEN)
(S)) devuetve(oprel, x6v)
Fig. 3.12. Diagrama de transiciones para operadores relacionales.
Ejemplo 3.8. Como las palabras clave son secuencias de letras, son la excepcion a la
regla de que una secuencia de letras y digitos que comience con una letra es un iden-
tificador. En vez de codificar las excepciones en un diagrama de transiciones, es me-
jor considerar las palabras clave como identificadores especiales, como en la seccion
2.7. Cuando se llega al estado de aceptacién de la figura 3.13, se ejecuta algin cé-
digo para determinar si el lexema que condujo al estado de aceptacion es una pala-
bra clave o un identificador.104 ANALISIS LEXICO
letra o digito
io letra otro .
ice gyi ih? owe as devuelve (obténcomplex (), instala_ick))
Fig. 3.13. Diagrama de transiciones para identificadores y palabras clave.
Una tecnica sencilla para separar las palabras clave de los identificadores es ini-
cializar adecuadamente la tabla de simbolos en donde se guarda la informacion so-
bre identificadores. Para los componentes léxicos de la figura 3.10, es necesario in-
troducir las cadenas if, then y else en la tabla de simbolos antes de que aparezca
ningin caricter en la entrada. También se pone una nota en la tabla de simbolos
del componente léxico que debe ser devuelto cuando se reconoce una de estas ca-
denas, La proposicion devuelve después del estado de aceptacion de la figura 3.13
utiliza obtén_complex() e instala_id\) para obtener el componente léxico y el valor
de atributo, respectivamente, que deben ser devueltos. El procedimiento instala_id)
tiene acceso al buffer, en donde esta localizado el lexema del identificador. Se exa-
mina la tabla de simbolos y si se encuentra el lexema marcado como una palabra
clave, instala_id() devuelve 0. Si se encuentra el lexema y es una variable de pro-
grama. instala-id() devuelve un apuntador a la entrada de la tabla de simbolos. Si
el lexema no se encuentra en la tabla de simbolos, se instala como una variable y se
devuelve un apuntador a la entrada recién creada.
El procedimiento obtén_complex busca el lexema de forma parecida en la tabla
de simbolos. Si el lexema es una palabra clave, se devuelve el correspondiente com-
ponente léxico: si no, se devuelve el componente léxico id.
Obsérvese que el diagrama de transiciones no se modifica si se reconocen pala-
bras clave adicionales: simplemente se inicializa la tabla de simbolos con las cadenas.
y componentes léxicos de las palabras clave adicionales,
digito digito
i Q + digito EB ~\to- ,
> 13-14) 15 16,
~ oN
digito digito
—+(20) +21) (22)
inicio
Fig. 3.14. Diagramas de transiciones para numeros sin signo en Pascal.3.4. RECONOCIMIENTO DE COMPONENTES LEXICOS 105
La técnica de colocar las palabras clave en la tabla de simbolos es casi indispen-
sable cuando el analizador léxico se codifica manualmente. De no hacerlo asi, el nu-
mero de estados en un analizador Iéxico para un lenguaje de programacion tipico es
de varios cientos, mientras que utilizando el truco, quiza baste con menos de cien
estados.
Ejemplo 3.9. Cuando se construye un reconocedor de numeros sin signo dados por
la definicién regular
ito’ (.digito” )? (E(+ | -)? digito’)?
surgen varias cuestiones. Obsérvese que la definicion tiene la forma digitos fraccién?
exponente?, donde fraccion y exponente son opcionales.
El lexema de un determinado componente léxico debe ser el mas grande posible,
Por ejemplo, el analizador léxico no debe detenerse después de aparecer 12 0 in-
cluso 12.3 cuando la entrada es 12 .3E4. Empezando en los estados 25, 20 y 12
de la figura 3.14, los estados de aceptacion se alcanzarin después de que hayan apa-
recido 12, 12.3 y 12.364, respectivamente, suponiendo que 12.3E4 vaya se-
guido de un caracter distinto de digito en la entrada. Los diagramas de transiciones
con estados de inicio 25,20 y 12 son para digitos, digitos fraccién y digitos frac-
cién? exponente, respectivamente, de modo que se deben probar los estados de ini-
cio en el orden inverso 12, 20, 25.
La accion, cuando se Mega a cualquiera de los estados de aceptacion 19, 24 6
27, es llamar al procedimiento instala_ntim, que introduce el lexema en una tabla
de numeros y devuelve un apuntador a la entrada creada. El analizador léxico de-
vuelve el componente léxico nam con este apuntador como valor lexico. Eh
nim >
Se puede utilizar la informacién sobre el lenguaje que no esta en las definiciones
regulares de los componentes léxicos para sefialar los errores en la entrada. Por
ejemplo, con la entrada 1.