Вы находитесь на странице: 1из 10

Resumen capitulo II y III

Un compilador sencillo de una pasada y Análisis léxico

Autor
Junior German
Hernandez García
Matricula
14-EISN-6-014
Asignatura
Compiladores e interpretes
Maestro
Benito Vinicio Rubio
Tema II. Un compilador sencillo de una pasada
Definición de la sintaxis
La sintaxis es la parte que estudia las reglas y principios que gobiernan la combinatoria
de constituyentes sintácticos y la formación de unidades superiores a estos. La sintaxis
estudia las formas en que se combinan las palabras, así como las
Traducción dirigida por la sintaxis
Una definición dirigida por sintaxis es un formalismo para especificar las traducciones
para las construcciones en función de atributos asociados con sus componentes
sintácticos. Utiliza una gramática independiente de contexto para especificar la estructura
sintáctica de la entrada, la idea es asociar con cada símbolo de la gramática un conjunto
de atributos (que luego veremos que pueden ser sintetizados o heredados) y además a
cada producción un conjunto de reglas semánticas para calcular los valores de los
atributos asociados con los símbolos que aparecen en esa producción. La definición
dirigida por sintaxis consiste en sí entonces de la gramática y el conjunto de reglas
semánticas. En una definición dirigida por sintaxis, para cada producción gramatical
AÆα se asocia un conjunto de reglas semánticas de la forma b:=f(c1,c2,…,ck) donde f es
una función y b es un atributo sintetizado de A o un atributo heredado de uno de los
símbolos gramaticales de la parte derecha de la producción y c1,c2,…,ck son atributos que
pertenecen a los símbolos gramaticales de la producción. Se dice que b depende de
c1,c2,…,ck.
Análisis sintáctico
Es la fase del analizador que se encarga de chequear el texto de entrada en base a una
gramática dada. Y en caso de que el programa de entrada sea válido, suministra el árbol
sintáctico que lo reconoce. En teoría, se supone que la salida del analizador sintáctico es
alguna representación del árbol sintáctico que reconoce la secuencia de tokens
suministrada por el analizador léxico.
En la práctica, el analizador sintáctico también hace:
• Acceder a la tabla de símbolos (para hacer parte del trabajo del analizador semántico).
• Chequeo de tipos ( del analizador semántico).
• Generar código intermedio.
• Generar errores cuando se producen.
En definitiva, realiza casi todas las operaciones de la compilación. Este método de trabajo
da lugar a los métodos de compilación dirigidos por sintaxis.
Traductores de expresiones simples
Sintaxis abstracta y concreta: un punto de partida útil para considerar la traducción de
una cadena de entrada es un árbol de sintaxis abstracta, donde cada nodo representa un
operador, y los hijos de ese nodo, los operando. Por contraste, un árbol de análisis
sintáctico se denomina árbol de sintaxis concreta, y la gramática subyacente, sintaxis
concreta del lenguaje. Los arboles de sintaxis abstracta, o simplemente arboles sintácticos
difieren de los árboles de análisis sintáctico en que las distinciones superficiales de forma,
sin importancia en la traducción, no aparecen en los arboles sintácticos.
Análisis léxico
Eliminación de e espacios en blanco y comentarios: el traductor de expresiones reconoce
todos los caracteres de la entrada, de modo que los caracteres extraños, como los espacios
en blanco, harán que falle. Muchos lenguajes permiten que aparezcan “espacios en
blanco” (caracteres en blanco, caracteres TAB y de nueva línea) entre los componentes
léxicos. Los comentarios también pueden no ser considerados por el analizador sintáctico
y el traductor, por tanto, también se pueden tratar como espacios en blanco.
Si el analizador léxico elimina los espacios en blanco, el analizador sintáctico nunca
tendrá que considerarlos.
Constantes: en cualquier momento que aparece un dígito solo en una expresión, parece
razonable poner una constante entera arbitraria en su lugar. Como una constante entera
es una secuencia de dígitos, pueden admitirse constantes enteras añadiendo
producciones a la gramática de las expresiones o creando un componente léxico para tales
constantes.
Reconocimiento de palabras claves e identificadores: los lenguajes utilizan
identificadores como nombres de variables, matrices, funciones y similares. A menudo,
una gramática para un lenguaje trata a un identificador como un componente léxico.
Un analizador léxico: cuando entre el analizador sintáctico y la cadena de entrada se
inserta un analizador léxico, este interactúa con los dos. Lee los caracteres de la entrada,
los agrupa en lexemas y pasa los componentes léxicos formados por los lexemas, junto
con los valores de sus atributos, a las etapas posteriores del compilador.
Incorporación de una tabla de símbolos
En informática, una tabla de símbolos es una estructura de datos que usa el proceso de
traducción de un lenguaje de programación, por un compilador o un intérprete, donde
cada símbolo en el código fuente de un programa está asociado con información tal como
la ubicación, el tipo de datos y el ámbito de cada variable, constante o procedimiento.
Una implementación común de una tabla de símbolos puede ser una tabla hash, la cual
será mantenida a lo largo de todas las fases del proceso de compilación de ticses.
Puede tratarse como una estructura transitoria o volátil, que sea utilizada únicamente en
el proceso de traducción de un lenguaje de programación, para luego ser descartada, o
integrada en la salida del proceso de compilación para una explotación posterior, como
puede ser por ejemplo, durante una sesión de depuración, o como recurso para obtener
un informe de diagnóstico durante o después la ejecución de un programa.
Los símbolos en la tabla de símbolos pueden referirse a constantes, a funciones o a tipos
de datos en el código fuente de un programa.
La tabla de símbolos forma parte de cada fichero que contiene el código objeto durante el
enlazado o linking de los diferentes ficheros; recae en la responsabilidad del linker o
enlazador resolver cualquier referencia no resuelta.
En general en la Tabla de símbolos (TS a partir de ahora) se realizan dos operaciones: la
inserción y la búsqueda.
En C la operación de inserción se realiza cuando se procesa una declaración.
Hay dos posibilidades: que la TS esté ordenada (o sea, nombres de variables por orden
alfabético) o que no esté ordenada.
En la búsqueda, se detectan los identificadores que no hayan sido declarados
previamente, emitiendo un mensaje de error.
 ejemplo en lenguaje C: Undefined símbolo 'x', si es una variable que desea usarse
pero no se declaró.
En la inserción, se detectan identififcadores que ya han sido declarados previamente,
emitiendo un mensaje de error
 ejemplo en C: multiple declaration for 'x' si x ya estaba en TS.
Máquinas de pilas abstractas
Una máquina de pila es un modelo computacional en el cual la memoria de la
computadora toma la forma de una o más pilas. El término también se refiere a un
computador real implementando o simulando una máquina de pila idealizada.
Adicionalmente, una máquina de pila también puede referirse a una máquina verdadera
o simulada con un conjunto de instrucciones de "0 operandos". En tal máquina, la
mayoría de las instrucciones implícitamente operan en valores en el tope de la pila y
reemplazan esos valores por el resultado. Típicamente tales máquinas también tienen una
instrucción "load" y una instrucción "store" que leen y escriben a posiciones arbitrarias
de la RAM. La ventaja de las máquinas de pila ("conjunto de instrucciones de 0
operandos") sobre las máquinas de acumulador ("conjunto de instrucciones de 1
operando") y las máquinas de registro ("conjunto de instrucciones de 2 operandos" o un
"conjunto de instrucciones de 3 operandos") es que los programas escritos para un
conjunto de instrucciones de "0 operandos" generalmente tienen una densidad de código
más alta que los programas equivalentes escritos para otros conjuntos de instrucciones.
Tema III. Analisis léxico
Función del analizador léxico
La función del analizador léxico es 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.

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. Esta interacción, suele aplicarse convirtiendo al analizador léxico en una
subrutina o corrutina del analizador sintáctico. Recibida la orden "obtén 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.

Manejo de los buffers de entrada


Un buffer es el área del almacenamiento primario destinada a contener datos durante
transferencia de entrada salida. Normalmente los datos se almacenan en un búfer
mientras son transferidos desde un dispositivo de entrada (como un ratón o mouse) o
justo antes de enviarlos a un dispositivo de salida (por ejemplo: altavoces). También
puede utilizarse para transferir datos entre procesos, de una forma parecida a los búferes
utilizados en telecomunicaciones. Un ejemplo de esto último ocurre en una comunicación
telefónica, en la que al realizar una llamada esta se almacena, se disminuye su calidad y
el número de bytes a ser transferidos, y luego se envían estos datos modificados al
receptor.
Técnica de “Pareja de buffers”
En la técnica de pareja de buffers se utiliza un buffer dividido en dos mitades de N
caracteres cada uno donde:
El número de caracteres en un bloque de disco marca el final del archivo fuente, al
principio, los dos apuntadores apuntan al primer carácter del próximo lexema que hay
que encontrar:
 El apuntador delantero: examina hacia delante hasta encontrar una
concordancia con un patrón. Una vez determinado el siguiente lexema, el
apuntador delantero se coloca en el carácter de su extremo derecho.
 El apuntador de lexema se queda al inicio del lexema y lo procesa.
Después de haber procesado el lexema, ambos apuntadores se colocan en el carácter
situado inmediatamente después del lexema.
Técnica de “Centinelas”
Si se utiliza la pareja de buffers, cada vez que se mueva el apuntador delantero se debe
comprobar si se ha salido de una mitad del buffer, si así ocurriera se deberá cargar la
segunda mitad. Es decir, para hacer avanzar el apuntador se realizan dos pruebas.
Se pueden reducir estas dos pruebas a una si se amplía cada mitad del buffer para admitir
un carácter centinela (carácter especial que no puede ser parte del programa fuente – eof)
al final.

Especificación de los componentes léxicos


Para especificar patrones para un componente léxico cada patrón concuerda con una serie
de cadenas, de modo que las expresiones regulares servirán como nombres para
conjuntos de cadenas.
Cadenas y lenguajes
El alfabeto o clase de carácter denota cualquier conjunto finito de símbolos (letras o
caracteres).
Conjunto {0,1} alfabeto binario
a, b, c, d, e, ... , z alfabeto
Código ASCII, EBCDIC alfabetos del computador
Cadena (frase o palabra): Es una secuencia finita de símbolos tomadas de un alfabeto.
Lenguaje: Se refiere a cualquier conjunto de cadenas de un alfabeto fijo.
También se puede extender el operador de “exponenciación” a los lenguajes definiendo
L° como { }
Sea L el conjunto {A, B, C, D, ...,Z, a, b, c, d,...,z} y D el conjunto {0, 1, 2, ..., 9}. Algunos
ejemplos de nuevos lenguajes creados a partir de L y D:
1. LUD es el conjunto de letras y dígitos.
2. LD es el conjunto de cadenas que consta de una letra seguida de un dígito.
3. L4 es el conjunto de todas las cadenas de cuatro letras.
4. L* es el conjunto de todas las cadenas de letras, incluyendo la cadena vacía ( ).
5. L(LUD)* es el conjunto de todas las cadenas de letras y dígitos que comienzan con una
letra.
6. D+ es el conjunto de todas las cadenas de uno o más dígitos.
Las expresiones regulares se utilizan para describir los componentes léxicos de un
lenguaje o tokens. Las expresiones regulares utilizan varios tipos de operadores para
definir los componentes léxicos:
• Paréntesis. Para agrupar símbolos
• Operación concatenación. Se permite la concatenación de cadenas.
• Operación alternativa. Se representa por |, y permite la elección entre dos o más
alternativas.
Componentes léxicos:
a) Identificador: (Letra seguida de letras y dígitos). Se puede definir a partir de dos
símbolos: letra y dígito.
letra (letra|dígito)*
b) Constante entera
(sin signo) digito+
(con signo) (+|-) digito+
c) Constante de punto flotante sin exponente
(+|-) digito+.digito+
Estas son breviaturas en la notación
1. Uno o más casos de. +
2. Cero o un caso. ?
Conjuntos no regulares son aquellos lenguajes que no se pueden describir con ninguna
expresión regular.

Reconocimiento de los componentes léxicos


En esta sección, se estudia el reconocimiento de los componentes léxicos y se utiliza como
ejemplo el lenguaje generado por la siguiente gramática.
prop -> if expr then prop
| if expr then prop else prop

expr -> término oprel término
| término
término -> id
| núm
donde los terminales if, then, else, oprel, id y núm generan conjuntos de cadenas dados
por las siguientes definiciones regulares:
if -> if
then -> then
else -> else
oprel -> < | <= | = | <> | > | >=
id -> letra ( letra | digito )*
núm-> digito+( . dígito+)? (E( + | - )? dígito+ .. )?
donde letra y dígito se han definido anteriormente.
Para este fragmento de lenguaje, el analizador léxico reconocerá las palabras clave if, then,
else, al igual que los lexemas representados por oprel, id y núm. Para simplificar las cosas,
se supone que las palabras clave son reservadas; es decir, no se pueden usar como
identificadores, núm representa los números enteros y reales sin signo de Pascal.
Además, se supone que los lexemas están separados por espacio en blanco, formados por
secuencias no nulas de espacios en blanco, caracteres TAB y caracteres de nueva línea. El
analizador léxico eliminará los espacios en blanco. Esto lo hará comparando una cadena
con la definición de la expresión regular eb siguiente.
delim -> blanco | tab | lineanueva
eb -> delim+
Si se encuentra una concordancia para eb, el analizador léxico no devuelve un
componente léxico al analizador sintáctico, sino que se dispone a encontrar un
componente léxico a continuación del espacio en blanco y lo devuelve al analizador
sintáctico.
El objetivo es construir un analizador léxico que aislé el lexema para el siguiente
componente Léxico del buffer de entrada y que produzca como salida un par formado por
el componente léxico apropiado y el valor de atributo, utilizando la tabla de traducción
mostrada a continuación. Los valores de atributo para los operadores relacionales están
dados por las constantes simbólicas MEN, MEI, IGU, MAY, MAI.

Un lenguaje para la especificación de un análisis léxico


Un analizador léxico o analizador lexicográfico (en inglés scanner) es la primera fase de
un compilador consistente en un programa que recibe como entrada el código fuente de
otro programa (secuencia de caracteres) y produce una salida compuesta de tokens
(componentes léxicos) o símbolos. Estos tokens sirven para una posterior etapa del
proceso de traducción, siendo la entrada para el analizador sintáctico (en inglés parser).
La especificación de un lenguaje de programación a menudo incluye un conjunto de reglas
que definen el léxico. Estas reglas consisten comúnmente en expresiones regulares que
indican el conjunto de posibles secuencias de caracteres que definen un token o lexema.
En algunos lenguajes de programación es necesario establecer patrones para caracteres
especiales (como el espacio en blanco) que la gramática pueda reconocer sin que
constituya un token en sí.

Autómata finito
Un autómata finito (AF) o máquina de estado finito es un modelo computacional que
realiza cómputos en forma automática sobre una entrada para producir una salida.
Este modelo está conformado por un alfabeto, un conjunto de estados finito, una función
de transición, un estado inicial y un conjunto de estados finales. Su funcionamiento se
basa en una función de transición, que recibe a partir de un estado inicial una cadena de
caracteres pertenecientes al alfabeto (la entrada), y que va leyendo dicha cadena a medida
que el autómata se desplaza de un estado a otro, para finalmente detenerse en un estado
final o de aceptación, que representa la salida.
La finalidad de los autómatas finitos es la de reconocer lenguajes regulares, que
corresponden a los lenguajes formales más simples según la Jerarquía de Chomsky.

Paso de una expresión regular a un afn


Los lenguajes regulares se llaman así porque sus palabras contienen “regularidades” o
repeticiones de los mismos componentes, como por ejemplo en el lenguaje L={abc,
abcabc, abcabcabc, …}. La regularidad de la palabra “abc” en el lenguaje L permite definir
muchos otros lenguajes basados en la idea de repetir esquemas simples. Esta es la idea
básica para formar los lenguajes regulares. Por otro lado, las expresiones regulares (ER)
son simplemente fórmulas cuyo propósito es representar un lenguaje.
Al tratar de encontrar una expresión regular para un lenguaje dado, mientras más
complejo sea el lenguaje es obvio que resulta más difícil encontrar por pura intuición
dicha expresión regular. En estos casos puede ser conveniente trabajar en forma
metódica.

Diseño de un generador de un análisis léxico


Un analizador léxico lee caracteres del archivo de entrada, donde se encuentra la cadena
a analizar, reconoce lexemas y retorna token. ... En cada aplicación, el problema de fondo
es la especificación y diseño de programas que ejecuten las acciones activadas por
patrones dentro de las cadenas.
Los pasos para la construcción de dicha herramienta son los siguientes:
1. Definir el lenguaje de especificación de las expresiones regulares.
2. Implementar un algoritmo que parece un archivo fuente que respete la especificación
dada y construya las estructuras de datos necesarias árbol sintáctico de las expresiones
regulares, entre otras.
3. Implementar un algoritmo que construya los AFD de cada expresión Regular.
4. Implementar un algoritmo que construya un AFN a partir de los AFD
5. Implementar un algoritmo que construya un AFD a partir del AFN
6. Minimizar el AFD
7. Generar un archivo de código fuente con las estructuras y los algoritmos genéricos
necesarios para simular el AFD.
Optimación de buscadores por concordancia de patrones basados en AFD.

Вам также может понравиться