letra| digito

Anuncio
TEORÍA DE LOS LENGUAJES DE PROGRAMACIÓN
TEMA 4
ANALISIS LÉXICO
Objetivos
2
Objetivos:

Concepto de un analizador léxico

Iteración entre el AL y AS

Especificación de los componentes léxicos de un lenguaje

Representación de los componentes léxicos de un lenguaje

Estructura de un analizador léxico

Construcción de un AL

Generadores automáticos de AL
Teoría de los lenguajes de programación - Tema 4
Índice
3
Léxico de un lenguaje:
4.1 Concepto de un analizador léxico
4.2 Iteración o comunicación entre el AL y el AS
4.3 Categorías léxicas de un lenguaje
4.4 Funcionalidad de un AL
4.5 Definición formalizada de un AL
4.6 Construcción de un AL
4.7 Generadores automáticos de AL
Teoría de los lenguajes de programación - Tema 4
4.1 Léxico - Concepto de un AL
4
Analizador léxico- se encarga de obtener y analizar las palabras que componen un texto fuente
Lexema - secuencia de caracteres con significado propio obtenidos de la entrada
Comp. léxico, categoría léxica (tokens) – conjunto de lexemas con significado propio,
que suelen definirse como un tipo enumerado
Patrón- modelo que describe el conjunto de lexemas de una categoría léxica
Texto fuente
Área_trianglo
:=
(base*altura)/2
Analizador
Léxico
Identificador (variable)
símb. asig
p_abrir
Identificador (variable)
operador
Identificador (variable)
p_cerrar
operador
const_entera
Teoría de los lenguajes de programación - Tema 4
4.1 Léxico - Concepto de un AL
Tabla que representa las descripciones de las categorías léxicas, para los lexemas de entrada
en el ejemplo anterior.
lexema
Categoría léxica
Descripción - patrón
área
p_ident
Letra seguida de letra o dígito
:=
p_asignar
:=
(
p_abrir
(
base
Ident
Letra seguida de letra o dígito
*
p_por
*
altura
p_ident
Letra seguida de letra o dígito
)
p_cerrar
)
/
P_div_real
/
2
P_cont_ent
Letra seguida de letra o dígito
Teoría de los lenguajes de programación - Tema 4
4.1 Léxico - Concepto de un AL
El AL asocia a ciertos componentes léxicos unos atributos que guarda en TS que son
necesarios en siguientes fases de la traducción
lexema
Categoría léxica
atributos
Descripción
área
p_ident
Nombre(área)
Letra seguida de letra o dígito
:=
p_asignar
-------
:=
(
p_abrir
------
(
base
Ident
Nombre(base)
Letra seguida de letra o dígito
*
p_por
-------
*
altura
p_ident
Nombre(altura)
Letra seguida de letra o dígito
)
p_cerrar
-------
)
/
P_div_real
-------
/
2
P_cont_ent
Valor(2)
Letra seguida de letra o dígito
El AL envía el componente léxico al AS bajo petición de este
Teoría de los lenguajes de programación - Tema 4
4.1 Léxico - Concepto de un AL
Para describir los patrones se utilizan la notación de expresiones regulares,
como descriptores de lenguajes regulares.
lexema
area
Categoría léxica
identificador
atributos
Descripción
Expresión regular
Nombre(area)
letra seguida de letra o dígito
Letra(letra|dígito)*
:=
simb_asignación
--
:=
:=
(
par_abrir
--
(
(
base
identificador
Nombre(base)
letra seguida de letra o dígito
Letra(letra|dígito)*
*
operador_*
--
*
*
altur
identificador
Nombre(altura)
letra seguida de letra o dígito
Letra(letra|dígito)*
)
par_cerrar
--
)
)
/
operador_/
--
/
/
2
const_entera
Valor(2)
Dígito seguido de dígito
Digito+
Teoría de los lenguajes de programación - Tema 4
4.2 Léxico – Comunicación entre AL y AS
8
Iteración entre AL y AS - se pueden destacar tres formas:

Ambas actividades se realizan de forma independiente, dos algoritmos independientes.
Al realizar los análisis de forma independiente, no se sabrá si la secuenciación de los
componentes léxicos es correcta hasta que se pase por el análisis sintáctico con la
correspondiente perdida de tiempo y memoria


- Ambas actividades se realizan de forma concurrente, un único algoritmo
En este caso se está cargando el analizador sintáctico de acciones que no son propias de
él, tales como ignorar los comentarios, saltos de líneas.
El analizador léxico es una subrutina o corrutina del analizador sintáctico,
Dos algoritmo donde uno usa el otro (ambos análisis avanzan simultáneamente), es el tipo
de iteración de nuestro estudio.
Prog.
fuente
Analizador Léxico
Comp. léxico
Obtener Comp. léxico
atributos
Tabla de símbolos
Teoría de los lenguajes de programación - Tema 4
Analizador Sintáctico
4.2 Léxico - Iteración entre AL y AS
9



En el análisis del programa fuente el AL debe conocer la forma de los
componentes léxicos
El AS debe configurar estructuralmente las piezas que recibe del AL
Dicha configuración permite la relación entre ambos analizadores, pues mientras
el AS pide el componente que tiene que recibir, es el léxico el que se la tiene que
enviar y coincidir.
Teoría de los lenguajes de programación - Tema 4
4.2 Léxico - Ejemplo de iteración entre AL y AS
10
•Los elementos de conexión se pueden ver en la siguiente gramática.
- Especificación sintáctica de las sentencias de asignación
G1=({ident, sim_asig, cte_ent, p_abrir, …}, N={sent_asig, Epresión, …},…
Sent_asig → ident sim_asig Expresion
Expression → Expresion Operador Operando
|Operando
Operando → ident | cte_ent|…..| p_abrir Expresión p_cerrar
Operador → operador_+ | operador_* | operador_/ |….
- Especificación léxica de los identificadores
G1=( ∑={ letra=a,b, digito=0,1}, {N={ident, sim_asig, cte_ent, p_abrir, p_cerrar, …},,…
ident → letra ident | digito ident | letra| digito
cte_ent→ digito cte_ent | digito
letra → a|….|z
digito→ 0|….|9
operador_+→ “+”
simb_asig→ “:=”
Teoría de los lenguajes de programación - Tema 4
4.2 Léxico-Ejemplo de iteración entre AL y AS
11




El alfabeto terminal de la gramática sintáctica {ident, cte_ent,…} coincide con el
alfabeto no terminal de la gramática léxica.
El alfabeto terminal de la gramática léxica coincide con el alfabeto del lenguaje
fuente, para el que se quiere construir el analizador léxico.
El alfabeto no terminal de la gramática sintáctica representan la estructura de
las palabras del lenguaje, para el que se quiere construir el analizador
sintáctico.
En definitiva mientras que el AS se encarga de la colocación de las piezas el AL
de la forma de cada una de ellas.
Teoría de los lenguajes de programación - Tema 4
4.2 Léxico- Ejemplo de iteración entre AL y AS
12
Comunicación entre el A. léxico y el A. sintáctico
Sent_asig
ident
Sim_asig
Expresión
Expresión
Operador
Operando
Sim_asig
Operando
Oper_/
P_abrir
ident
A sintáctico
Cte_ent
Expresión P_cerrar
P_abrir
….
P_cerrar
Oper_/
Cte_ent
A. léxico
area
:=
(
base
*
altura
)
/
Teoría de los lenguajes de programación - Tema 4
2
Entrada
4.2 Léxico- Iteración entre AL y AS
13
A continuación se proponen algunas razones de esta separación:

Modularidad
La separación de tareas facilita el mantenimiento y mejora del traductor

Simplificación del diseño
Se puede simplificar una, otra o ambas fases.
Permite realizar modificaciones o extensiones al lenguaje
Elimina procesos innecesarios en el AS, tratando comp. léxicos especiales
Los lenguajes regulares son más fácil de tratar



Eficiencia
Permite construir un procesador especializado y más eficiente.
Eficacia con técnicas especiales de manejo de buffers por la complejidad de lectura escritura
Portabilidad
Las peculiaridades del alfabeto de entrada (códigos: ASCII, EBCDIC,…)
Símbolos especiales y otras anomalías propias de los dispositivos de entrada pueden quedar limitados
al ámbito del AL,
Si se quiere cambiar begin y end por { y } solo hay que cambiar el AL
Patrones complejos
Centrarse en el reconocimiento de componentes complejos y resolver ambiguedades.
Teoría de los lenguajes de programación - Tema 4
4.3 Léxico- Categorías léxicas de los lenguajes de programación
14
Entre las categorías léxicas habituales a usar en los LP están las siguientes:






Identificadores de objetos : nombres de variables, clases , métodos, tipos definidos por el usuario,…
Constantes numéricas : literales que representan valores enteros, reales etc,
Literales – representan cadenas concretas de caracteres
Operadores - operadores para realizar las tareas propias de cálculo
Símbolos especiales - separadores y delimitadores de diferentes construcciones
Palabras reservadas - Palabras con significado concreto dentro del lenguaje
Categoría léxicas especiales:

Comentarios - Información que se incluye en el texto del programa fuente

Separadores - para separar componentes léxicos , blancos, tabuladores, fin de línea,…

Fin de entrada - categoría léxica ficticia
Teoría de los lenguajes de programación - Tema 4
4.4 Léxico - Funcionalidad del AL
15
Acciones principales :

Leer la cadena de caracteres de la entrada (buffer), bajo petición del AS.

Analizar y acumular el carácter si no se ha determinado aún un token (una categoría léxica)





Entregar al AS la unidad sintáctica, junto con información adicional relevante para las siguientes fases
del traductor (atributo).
En lenguajes sencillos con variables globales, declaraciones,.. la información se guarda en TS.
Sin embargo en lenguajes imperativos la información se guarda durante el AS.
En ocasiones sólo se puede determinar un token cuando se ha recibido un carácter que pertenece al
siguiente token. En este caso se debe reinsertar dicho carácter a la entrada para realizar el análisis
léxico de la siguiente petición del analizador léxico ).
Rechazar aquellos caracteres o conjunto de éstos que no pertenezcan al lenguaje, indicándolo mediante
mensaje de error al usuario
Manejar el fichero fuente ( abrir, leer, cerrar).
Teoría de los lenguajes de programación - Tema 4
4.4 Léxico - Funcionalidad del AL
16
Acciones secundarias:


Ignorar del programa fuente los comentarios, los espacios en blanco, tabuladores, retorno
de carro, etc, y en general, todo aquello que carezca de significado según la sintaxis del
lenguaje.
Contar los saltos de línea y asociar los mensajes de error con el número de la línea del
programa fuente donde se producen.

Si el formato de línea no es libre, informar del fin de línea.

La posibilidad de utilizar un preprocesador para expandir macros.
…………………………………
Teoría de los lenguajes de programación - Tema 4
4.4 Léxico - Estructura funcional de un Analizador léxico
17
La función principal del AL es entregar el componente léxico al AS
El resto de las funciones dependen del traductor y del propio lenguaje a procesar
Interfaces en un analizador léxico:

Interfaz con el analizador sintáctico - entrega del token

Interfaz con entrada - leer y analizar el siguiente lexema

Interfaz con la tabla de símbolos - guarda el lexema de los identificadores y valor de las constantes

Interfaz con el tratamiento de errores - lee un carácter que no es del lenguaje o no encuentra ningún
lexema que concuerde con los patrones especificados
siguiente
Fichero
Comp. léxico
Siguiente
carácter
fuente
Guardar
lexema
Analizador
Léxico
Siguiente
token
Mensaje
Error
Interfaz T. S.
Interfaz T.E.
Tabla de
símbolos
Trat. de
errores
Teoría de los lenguajes de programación - Tema 4
Analizador
Sintáctico
4.4 Léxico - Estructura funcional de un AL
18
Gestión de errores

Detección: imposibilidad de concordar un prefijo de la entrada con ningún patrón.
Errores más frecuentes:

presencia de un carácter que no pertenece al vocabulario terminal.

escritura incorrecta de un componente:
identificador, constante, palabra reservada, etc.

Tratamiento: (dos modalidades)

Sin recuperación: se detecta el error y se cancela el análisis del programa fuente,
escribiendo el mensaje de dicho error

Con recuperación: se detecta un error, se toma alguna acción que permita seguir con el
análisis, tras haber advertido del error.
A veces se eliminan los caracteres de la entrada restante hasta que el (anal_lex (token,..)) pueda
reconocer un patrón ( por ejemplo un delimitador ).
En otras ocasiones se utiliza un recuperador de errores, que no es más que una “reparación” para
continuar con el análisis.
Teoría de los lenguajes de programación - Tema 4
4.5 Léxico - Especificación de los componentes léxicos
19
Especificación de los componentes léxicos de un analizador léxico
Podemos destacar tres modalidades a la hora de la especificación del léxico:

No formalizada
Describiendo los componentes léxicos por medio de un lenguaje ordinario, sin aplicar reglas
para su definición.

Formalizada
Describiendo los componentes léxicos por medio de mecanismos regulares

Especificar un token de una manera formalizada, consiste en dar una expresión regular (o
patrón) que describe, el conjunto de lexemas asociados

A partir de las expresiones regulares podemos transformarlas en otros mecanismos
regulares que facilitan la especificación de algoritmos para su reconocimiento.

A la hora de la especificación lexicográfica de un lenguaje habrá que crear la relación
de todas las piezas sintácticas, con sus definiciones léxicas.

Gráfica
Mediante la utilización de algún método gráfico, como los diagramas sintácticos que también se
utilizan para especificar las características sintácticas.
Teoría de los lenguajes de programación - Tema 4
4.5 Léxico - Descripción formal de las categorías léxicas
20
Simulación de las categorías léxicas mediante diagrama de transiciones
Categoría léxica Identificador de java: Descripción por medio de una ER
Identificador →( letra | $ | ´_´) ( letra | digito | $ | ´_´)*
letra → [a-z] dígito → [0-9]
Letra,digito,$,-
Letra,$,q0
q1
&
q2
(* Seudocódigo que simula el anterior diagrama de transiciones . *)
Estado:=0; (* estado inicial *)
REPETIR
obtener (símbolo)
CASE estado OF
0 : CASE símbolo OF Letra, $, _ : estado:=1; otro: llama_error END;
1 : CASE símbolo OF Letra, dígito, $,_: estado:=1; &: estado:=2; otro: llama_error END;
ELSE llama_error END;
UNTIL estado =2 or llama_error
Si estado no es de aceptación llama_error
Teoría de los lenguajes de programación - Tema 4
4.5 Léxico - Descripción formal de las categorías léxicas
Simulación de las categorías léxicas mediante tabla de transiciónRepresentación tabular convencional de la función de transición δ, que toma dos argumentos (estado,
entrada) y devuelve un estado o error
letra, $, _
digito
&
q0
q1
error
error
q1
q1
q1
aceptar
q2
error
error
error
(*Pseudocódigo que simula la anterior tabla de transiciones.*)
Estado:=0; (* estado inicial *)
REPETIR
obtener (símbolo);
CASE símbolo OF
letra : entrada:= letra; dígito: entrada:=dígito; & : entrada:= &; otro: llama error;
END ;
estado:= tabla [estado, entrada ];
If estado=”error” llama_error;
UNTIL estado=”aceptar”
Teoría de los lenguajes de programación - Tema 4
4.6 Léxico - Construcción de un analizador lexicográfico
22
Construcción de un analizador lexicográfico
Podemos destacar tres formas básicas para construir un analizador lexico:



Ad hoc. Consiste en la codificación de un programa reconocedor que no sigue los
formalismos propios de la teoría de autómatas. Este tipo de construcciones es muy
propensa a errores y difícil de mantener. Se basa en el uso de sentencias if y case
para simular las posibilidades que se pueden dar en la lecturas de los caracteres de
entrada para formar los componentes léxicos.
Mediante la implementación manual de los autómatas finitos. Este mecanismo
consiste en identificar la colección de categorías léxicas (tokens) en construir los
patrones necesarios para cada categoría léxica, construir sus autómatas finitos
individuales, fusionarlos y estructurarlos por medio de un mecanismo selector (
también llamado máquina discriminadora determinista) ,finalmente, implementar los
autómatas resultantes.
De forma automática. mediante un metacompilador, un generador automático de
analizadores léxicos.
Teoría de los lenguajes de programación - Tema 4
4.6 Léxico – Construcción de AL de forma manual
23
La comunicación entre el AL y AS:
Se hace por medio de unas variables globales que devuelven el valor y el tipo enumerado de la
pieza.
Token (pieza) - contiene las diferentes piezas que el AL va reconociendo del texto de
va a pasar al AS bajo su petición
entrada y
Para representar las piezas sintácticas en la implementación del analizador léxico se suele
emplear un tipo enumerado formado por nombres significativos.
Con el tipo enumerado se van a tener todas las piezas que se pueden reconocer por el léxico.
Token= record Tipo: TipoToken; lexema:String [] end
TipoToken= ( TK_ident, TK_punto, TK_mas, ….. , TK_error)
Teoría de los lenguajes de programación - Tema 4
4.6 Léxico – Construcción de AL de forma manual
24

Esquema estructural de un analizador léxico
Siguiente lexema
Entrada
Lexema analizar
Fichero fuente
A.S
Delimitador,..
Modulo selector
Mensaje de error
tokens
otros
return(Tok)
identificador
literal
return (Tok,val)
return Tok,Lex)
Teoría de los lenguajes de programación - Tema 4
4.6 Léxico - Construcción de un analizador lexicográfico
25
Condiciones iniciales
Antes de llamar por primera vez el AS al AL para obtener una pieza ha de realizar:

Inicializar el contenido de la tabla de palabras reservadas:
Nombres de las palabras reservadas
Longitud del lexema que forma la palabra reservada
Representación interna de la palabra reservada

Leer la primera línea y ponerla en el buffer de entrada,

Saltar blancos, tabuladores (caracteres no significativos)

Posicionarse al principio del lexema a analizar
Teoría de los lenguajes de programación - Tema 4
4.6 Léxico - Construcción de un analizador lexicográfico
26
Lectura de entrada- gestión del buffer
La lectura se realiza por líneas que se lleva a una estructura estática, así se facilita el examen de los
símbolos por adelantado. Pudiendo retroceder sin mayor complejidad, llevando la contabilidad de
los caracteres leídos.
línea
lexema
apuntadores
inicio
posición
límite
Línea , vector de caracteres de la última línea leída del fichero fuente
Los punteros inicio y posición señalan el primer carácter del lexema que hay que analizar
El puntero posición (columna) va avanzando hasta encontrar un componente léxico
Encontrado el siguiente lexema, inicio y posición se coloca en el carácter del siguiente lexema
Entre inicio y posición delimitan el lexema
Al devolver el componente léxico, inicio toma el valor de la posición (el primer carácter del
siguiente lexema)
Teoría de los lenguajes de programación - Tema 4
4.6 Léxico- Construcción de un analizador lexicográfico
27
Caracteres por adelantado
Caracteres que han de examinarse más allá de la terminación de un lexema para decidir si la
pieza que corresponde a ese lexema.
++, area:=
El número de caracteres por adelantado necesarios para analizar un lexema determinan la
complejidad del analizador léxico.
Situaciones posibles que podemos encontrar en la delimitación de los lexemas:
- La longitud del lexema es desconocida, su fin se encontrará cuando se llega a un carácter que no
forma parte de su definición. area:= , area :=
- La longitud del lexema es conocida, su fin se encontrará cuando se llega al final de la cuenta de
los caracteres considerados en dicho lexema.
Teoría de los lenguajes de programación - Tema 4
4.6 Léxico - Construcción de un analizador lexicográfico
28
Prioridad de tokens
-
Cuando se está analizando un lexema se da prioridad al token con el lexema más largo que
se reconoce primero: ejemplo ´+´ y ´+=´ este último es el primero, 23.45 se trata de un
componente léxico constante real
-
Si el mismo lexema se puede asociar a dos tokens, estos patrones estarán definidos en el
orden de aparición.
Ejemplo:
Palabras reservadas { case, while,….} formadas por una secuencia de símbolos alfabéticos
Identificadores – letra (letra |dígito)* símbolos alfabéticos seguidos de alfanuméricos
Teoría de los lenguajes de programación - Tema 4
4.6 Léxico - Construcción de un analizador lexicográfico
29
Forma de tratar las palabras reservadas
Resolución implícita
Reconociendo todas como identificadores, utilizando una tabla adicional con las palabras
reservadas, que se consulta para ver el lexema reconocido es un identificador o palabra
reservada
Si es_palabra_reservada ( lexema, tabla_palabras_reservadas) Entonces
TK_palabra_rservada
Resolución explícita
Se indican todas las expresiones regulares de todas las palabras reservadas y se integran los
diagramas de transiciones resultantes de su especificaciones en una sola
If [f|F] [o|O] [r|R] return (Token_for)
If [w|W]…..[e|E]
return (Token_while)
………..
[a-zA-Z]( [a-zA-Z]|[0-9])* return (Token_identificador)
Teoría de los lenguajes de programación - Tema 4
4.6 Léxico - Construcción de un analizador lexicográfico
30
Módulo selector
Módulo que mediante el primer carácter del lexema permite determinar por medio de una
estructura de bucles anidados (CASE) qué AFD puede simular el reconocimiento del lexema de la
entrada y devolver la pieza sintáctica correspondiente. En el caso de no reconocerlo se creará un
mensaje de error.
El módulo selector no intenta reconocer la entrada sino segmentarla conociendo el primer carácter
del lexema.
El módulo selector actúa repetidamente sobre la entrada, empezando siempre en cada caso en
punto distinto pero siempre en estado inicial de un AFD
Seleccionar según el primer
símbolo del lexema y
devolver el comp. léxico
Modulo selector
letra
dígito
Pal_reservadas
Rec_ identificadores
Rec_constantes
……………..
´´
Rec_literales
4.6 Léxico - Construcción de un analizador lexicográfico
31
En cada una de las alternativas el módulo selector ha de realizar las operaciones:
- Terminar de leer el lexema
- Determinar el token de que se trata y cuáles son sus atributos
- Devolver el token y sus atributos en las variables globales correspondientes
Diagrama de bloques de un analizador léxico
Abrir
ficheros
Inicializar
tabla
Leer
entrada
siguiente
componenteo
Analizador
léxico
Comp_lex_finito
'a'..'z'
Componente
cerrar
ficheros
Selector autómatas
AFD identificador
'0'..'9
''''
Teoría de los lenguajes de programación - Tema 4
AFD cte_real o
AFD cte entera
AFD cadena
4.6 Léxico - Implementación manual de un AL
32
Antes de llamar por primera vez al AL el AS para obtener una pieza el AL hace:
InicializarAnalizadorLexico
Inicializar el contenido de la tabla de palabras reservadas:


Nombres de las palabras reservadas

Longitud del lexema que forma la palabra reservada

Representación interna de la palabra reservada

Leer la primera línea y ponerla en el buffer de entrada

Saltar blancos (caracteres no significativos)

Obtención de un componente léxico (pieza)
ObtenerPieza;
Posicionarse al principio del lexema a analizar
Obtener el componente léxico del texto fuente
Teoría de los lenguajes de programación - Tema 4
4.6 Léxico - Implementación manual de un AL al que inicializa el AS
33
Procedure Analisis_Sintáctico;
Begin
InicializarAnalizadorLexico; (*inicializar palabras reservadas, saltar blancos *)
ObtenerPieza; (* primera pieza*)
AnPrograma; (* símbolo inicial de la gramática*)
ComprobarFinalAnálisis; (* comprobar si pieza es p_ultima *)
End;
Para obtener una pieza a petición del AS, el analizador léxico determinará de que
token se trata para comparar con el pedido del AS
Teoría de los lenguajes de programación - Tema 4
4.6 Léxico - Implementación manual de un AL
34
Módulo central que devuelve la pieza correspondiente al lexema de entrada
ObtenerPieza();
…
BuscarInicio
Inicio := posición;
case linea [inicio] of
Letra: tratar_id ;
Digito: tratar_cte ;
‘+’ : pieza:=TKN_SUMA;
………………..
‘<’: Ver_si_menor
‘{‘ : begin saltarComentario ; Obtener Pieza
‘EOF’ : TKN_EOF;
else begin errorlexicográfico ; ObtenerPieza ;
…….
Teoría de los lenguajes de programación - Tema 4
Lexicografía - Implementación manual de un AL
35
Ejemplo simple:
main nombre_fuente is <objetos> begin <operaciones> end
AnPrograma, procedimiento asociado al símbolo inicial de la gramática sintáctica, trata de
construir de una forma ficticia el árbol sintáctico
Procedure AnPrograma;
begin
Aceptar (prmain);
Aceptar (pId);
Aceptar (prIs);
AnObjetos;
Aceptar(prbegin)
AnOperaciones;
Aceptar (prend);
end.
Comprueba si la pieza pedida por el AS es la obtenida por el AL
Procedure Aceptar (p: piezaSint);
begin
If pieza= p then ObtenerPieza()
else ErrorSintactico
end;
Teoría de los lenguajes de programación - Tema 4
Lexicografía- Implementación manual de un AL
36
Analiza el tipo de objeto
Procedure AnObjetos;
Begin
IF pieza= prType THEN AnDefTipo;
IF pieza= p_id THEN AnDefVar;
IF pieza= prPrcedure THEN AnDefProcedure;
IF pieza= prFunction THEN AnDefFunction;
…………….
End;
Procedure AnOperaciones();
………………………………
ComprobarFinalAnálisis;
La tarea de reconcimiento de los tokens del texto fuente concluye con (EOF). Cuando el AL encuentra
esa marca, ha de indicar AS de alguna forma que ha concluido el reconocimiento de tokens en el texto
fuente.
Para ello, el AL pone en la variable token un símbolo especial, él cual va a servir al modulo selector de
dicho analizador para que devuelva al sintáctico una pieza ficticia (p_ultima). Pieza que el analizador
sintáctico espera para finalizar, en otro caso se producirá una situación de error.
Teoría de los lenguajes de programación - Tema 4
Ejemplo - Estructura de un lenguaje
37
main nombre_fuente is <objetos> begin <operaciones> end
*objetos: Tipos type tipo_vector is array [ cte_ent .. cte_ent ]of <tipo_basico> ;
tipo_basico - integer,real,boolean o string
type tipo_registro is record <componentes> end record ;
componente - nom_camp1,nom_camp2,..: <tipo_basico> ;
variables nom_var0 , nom_var1 ,... : <tipo> ;
tipo – tipo_basico, vector, registro
………………………
* operaciones:
op. control while <expression> loop <operaciones> end loop ;
loop <operaciones> end loop ;
op. Selección if<expression>then<operaciones>else<operaciones> end if ;
case expresión is <alternativas> end case ;
<alternatives> when cte_ent | cte_ent |….:
op. e/s
put ( expr0, expr1,...) ; get ( var0 , var1 ,...) ;
asignación var_0 , var_1 ,... := expresión ;
llamada
Llama_proc ( par_act1 , par_act2 , ... ) ;
expresión operandos - variables, constantes enteras, reales, lógicas y operadores +, -, *,div, <=,!=,…
Teoría de los lenguajes de programación - Tema 4
Ejemplo - Componentes léxicos del lenguaje
38

Componentes léxicos del lenguaje
Componentes léxicos finitos:
- palabras reservadas: main,begin,end, ……
- operadores: =,<=,!=,*,…
- separadores: (,[,’,’,’;’,…
-…
Componentes léxicos infinitos:
- identificadores: { lenguaje regular } – componente léxico ident
- constantes enteras : { lenguaje regular } – componente léxico cte_ent
- constantes reales: { lenguaje regular } – componente léxico cte_real
- cadena: { lenguaje regular } – componente léxico cadena
Teoría de los lenguajes de programación - Tema 4
Ejemplo - Definición léxica que denota los identificadores
39
Palabras que comienzan por letra minúscula seguida de letra , digito o el símbolo subrayado (_),
no pudiendo darse mas de dos subrayados consecutivos , ni finalizar en subrayado
Definición regular que denota los identificadores - ident :
Ident:
letra_min (letra_min| digito |_letra_min| _digito|_ _ letra_min| _ _digito)*
letra_min: 'a'..'z' ; digito : '0'..'9'
- Autómata finito determinista AFD que reconoce los identificadores -
ident
a-z,0-9
a-z
q0
_
q1
_
q2
a-z,0-9
a-z.0-9
Teoría de los lenguajes de programación - Tema 4
q3
Ejemplo - Implementación de un AL
40

Analizador léxico independiente del analizador sintáctico
Abrir
ficheros
Diagrama de bloques de un analizador léxico
Leer
entrada
Reconocer
palabra
Comp_lex_fin
'a'..'z'
Escribir
salida
Selector autómatas
'0'..'9
''''
cerrar
ficheros
AFD identificador
AFD cte_real o
AFD cte entera
AFD cadena
Teoría de los lenguajes de programación - Tema 4
Ejemplo - Implementación de un AL en C++
41
#include <stdio.h>
#include <string.h>
#include <cTipo.h>..
#define LONG_BUFFER 1024
#define LONG_LEX …
#define PALABRAS_RES …
typedef enum { TK_BEGIN, TK_END, TK_PARD, TK_ID, TK_NUM, TK_EOF, TK_ERROR,… } tipo_token;
typedef enum { INICIO, IN_ID, IN_NUM, IN_PARD, IN_PARI, IN_EOF, ERROR, ACEPTACION,… } estado;
typedef struct { tipo_token tipo; char lexema[LONG_LEX]; }Token;
Token PalabrasReservadas[PALABRAS_RES]={ {TK_BEGIN, "begin"}, {TK_END, "end"}, … };
int nlinea=0; int ncolumna=0;
char buffer[LONG_BUFFER];
char *nombreFichero;//Nombre del fichero fuente
FILE* entrada; //Fichero de entrada
Teoría de los lenguajes de programación - Tema 4
Ejemplo - Implementación de un AL en C++
42
Lexico( char * nombreFichero);
Token EsPalabraReser (char *);
char obtenerCa r(FILE *);
void retocederCar (void);
Token obtenerToken(FILE *);
int esDelimitador (char c) ; //devuelve 1/0 si c es un blanco, tab, \n
};
Lexico::Lexico(char *NombreFichero) {
entrada=fopen(unNombreFichero, "rt");
if((entrada==NULL)) { cout<<"No se puede abrir el archivo"<<endl; system("pause"); exit(-2); }
}
Token EsPalabraReservada(char *s) {
int i=0; Token token;
if (strcmp(s, PalabraReservadas[i].lexema)==0) {return(PalabrasReservadas[i]);}
strcpy(token.lexema, s);
token.tipo=TKN_ID;
return(token);
}
Teoría de los lenguajes de programación - Tema 4
Ejemplo - Implementación de un AL en C++
43
char obtener_Car( FILE *fp) {
char c;
static int n; //longitud línea leida, se guarda valor de llamada a llamada
if (( ncolumna==0) || (ncolumna==n) ) {
if (NULL!=fgets(buffer, Long_Buffer, fp)) /* lee hasta el salto de linea */
{ n=strlen(buffer); ncolumna=0; nlinea++;}
else { return(EOF); }
}
c=buffer[ncolumna++];
return (c);
}
void retrocederCar() { ncolumna−−;}
int esDelimitador(char c) { char delimitadores[3]={’ ’, ’\t’, ’\n’};
int i; for (i=0;i<3;i++) { if (c==delimitadores[i]) {return(1);}
return (0);}
Teoría de los lenguajes de programación - Tema 4
Ejemplo - Implementación de un AL en C++
44
*******************************************************************
Token obtenerToken (FILE *fp) {
char c; Estados estado=INICIO; Token token;
int indice=0; //indice al caracter actual del lexema
while (estado!=FINAL) {
switch (estado) {
case INICIO: { c=obtenerCar (fp); while ( esDelimitador (c)) {c=obtenerCar(fp);}
if (esAlfabetico ((int) c)) { estado=IN_ID; token.lexema[indice++]=c;}
else if esDigito ((int) c)) { estado=IN_NUM; token.lexema[indice++]=c;}
else if (c==’)’) { token.tipo=TKN_RPAREN; estado=FINAL; token.lexema[indice++]=c;}
else if (c==’:’) {estado=IN_ASSIGN;token.lexema[indice++]=c;}
else if (c==’=’) {estado=TKN_ASSIGN;estado=FINAL; retrocdeCar(); indice--;}
……………………………….
else if (EOF==c) {token.type=TKN_EOF;estado=FINAL }
break; }
Teoría de los lenguajes de programación - Tema 4
Ejemplo - Implementación de un AL en C++
45
case IN_ID: { c=obtenerCar (fp); token.lexema[indice++]=c;
if (! ( esAlfanumerico( (int) c) ) || (c==’_’) ) )
Token.ipo=TKN_ID; estado=FINAL; retrocedeCar(); indice−−;
token.lexema[indice]=’\0’;
token=esPalabraResser(token.lexema); }
break; }
case IN_ASSIGN: {c=obtenerCar(fp);token.lexema[indice++]=c;
if (c==’=’) { token.tipo=TKN_ASSIGN; estado=FINAL; indice−−; }
break; }
……………………………
default: { token.tipo=TKN_ERROR; estado=FINAL; token.lexema[indice++]=c; }
} //end switch
}//end while
if (token.tipo==TKN_ERROR) { fprintf (stderr, "\nLinea %d:%d, Error: \n", nlinea, ncolumna, c);}
token.lexema[indice]=’\0’; //FINALIZA LA CADENA
return(token);
} }//end obtenerToken
Teoría de los lenguajes de programación - Tema 4
Ejemplo - Implementación de un AL en C++
46
I**********************************
int main (int argc, char **argv){
FILE *fp; Token token;
if (argc==2) {
if ( NULL== (fp= fopen(argv[1],"r")) ) { fprintf(stderr, “error en apertura de fichero\n", argv[1]);
return(0);
}
else { token=obtenerToken(fp);
while (TKN_EOF != token.tipo) { fprintf(stderr,"(%d,%s) ", token.tipo, token.lexema);
token=obtenerToken (fp);
}
printf("\n%d lineas analizadas", nlinea);
return(0);
}
Teoría de los lenguajes de programación - Tema 4
Ejemplo - Implementación de un AL en C++
47
#include <iostream.h> #include “ cSintactico.h” using namespace std:
Int main (){
cSintactico anSintactico(“entrada.txt”);
return 0;
}
#ifndef “ cSintactico.h” #define “ cSintactico.h” #include “cLexico.h” using namespace std:
class cSintactico {
private: cLexico anLexico:
public: aSintactico( char * fuente);
aSintacitco();
void anPrograma();
………………………..
cSintactico::cSintactico( char * fuente){
lexico (fuente); token =lexico.obtenerToken()
programa();
}
#ifndef “ cLexico.h” #define “ clexico.h” #include “cLexico.h” using namespace std:
File * f; Token token;
public: cLexico();
-------Teoría de los lenguajes de programación - Tema 4
Descargar