Compilador - facultad de ingenieria de sistemas

Anuncio
Facultad de Ingeniería de Sistemas
Lenguajes y Compiladores
Introducción
Compiladores
1
Objetivos
Conocer los fundamentos de construcción de
Compiladores en todas sus fases, presentando los
conceptos básicos, definiciones formales, técnicas
utilizadas, las clases de compiladores, el contexto en
el que se desarrollan, así como el tratamiento y
recuperación de errores
Aplicar estos conceptos al desarrollo de:
Software de base
Software de uso específico
Interfaces de usuario
Compiladores
2
Introducción
¿Por qué es importante el estudio de compiladares?
Conocer el diseño de los compiladores y su efecto
sobre los lenguajes:
Permite desarrollar algoritmos eficientes: por ejemplo
cuando usar recursión.
Mejora el uso del lenguaje disponible: si el uso de
apuntadores es eficiente o no.
Ayuda a la depuración de los errores tanto sintácticos
como semánticos
Compiladores
3
Introducción
En 1940 surge el 1° lenguaje utilizado en la programación de
computadoras : “El lenguaje de máquina” (lenguaje de 1era
generación).
¿Cuál era ventaja de programar en lenguaje de máquina ?
El lenguaje de máquina, es el único lenguaje que la
computadora entiende directamente.
¿Cuáles eran los inconvenientes o desventajas?
Dificultad y lentitud en la codificación. Gran dificultad para
verificar y poner a punto los programas.
Compiladores
4
Introducción
>
Las desventajas
Las ventajas.
Surge la necesidad de buscar otros lenguajes.
¿ Que sucedió a comienzos de la década de 1950 ?
Criterio :
Usar notación simbólica.
¿Cómo se llamó a esos lenguajes?
Fue el primer intento.
Esos lenguajes fueron de alto o bajo nivel?
¿Esos lenguajes presentaron la mayoría de inconvenientes
que presentaba el lenguaje de máquina?.
Compiladores
5
Introducción
La interface (de programación) entre los humanos y
las máquinas son los Lenguajes de programación: La
solución a un problema se especifica a través de un
programa fuente escrito en un Lenguaje de
programación.
Es necesario un proceso de traducción para que los
programas fuentes sean entendidos (ejecutados)
Los compiladores son necesarios para el desarrollo
de cualquier sistema, caso contrario tendríamos que
programar en lenguaje ensamblador o peor aún en
lenguaje máquina
Compiladores
6
Lenguajes de programación
Los lenguajes de programación han evolucionado
Lenguaje de máquina: combinación de 1’s y 0’s
Lenguaje montador (ensamblador): uso de mnemónicos
y direcciones de memoria
Lenguajes basados en cálculos numéricos:
» ForTran, AlGol, PL/1, Pascal, Basic
Lenguajes para los negocios: COBOL
Lenguajes para inteligencia artificial: LISP
Lenguajes para sistemas: C
Lenguajes orientados a objetos: C++, Object Pascal
Lenguajes visuales: Entornos de desarrollo
*
Compiladores
7
Introducción
Lenguaje Objeto: Conjunto de instrucciones que un
computador entiende y ejecuta, es una combinación
de 1’s y 0’s.
Lenguaje ensamblador: Conjunto de instrucciones
cuyas operaciones se especifican a través de
mnemónicos que representan códigos de operaciones.
Es como un lenguaje objeto codificado.
Lenguaje
de
programación:
Conjunto
de
instrucciones más cercanas al lenguaje humano y que
permiten especificar algoritmos y estructuras de
datos.
Compiladores
8
Introducción
Lenguajes de programación
Lenguaje Objeto
Lenguaje Natural
Compiladores
9
Introducción
Programa
fuente
Escrito en
Lenguaje de
programación
Traductor
Lenguaje Natural
Ensambladores.
Compiladores.
Interpretes.
Lenguaje Objeto
Compiladores
10
Traducción
La idea básica es tener un traductor que permita al
computador “entender” (ejecutar) un programa
escrito en un lenguaje de programación.
Los softwares que realizan estas “traducciones” son
conocidos como Compiladores
En una visión simplista el compilador recibe una
programa fuente y genera un programa objeto.
Fuente
Compilador
Objeto
Compiladores
11
Tipos
Ensamblador: recibe un programa en lenguaje
ensamblador y genera programa objeto.
Compilador: recibe un programa escrito en un
lenguaje de programación y genera un programa
objeto.
Intérprete: Analiza una instrucción fuente y la
ejecuta directamente sin generar código objeto.
Preprocesador. Permite sustituir macros, incluir
archivos, entre otras funciones. Generalmente es un
paso anterior a la traducción.
Compiladores
12
Introducción
Programa
fuente
assembly
language
Ensamblador
Traductor
Lenguaje Objeto
Compiladores
13
Introducción
Programa
fuente
Escrito en
Lenguaje de
Programación
de A.N.
Compilador
Traductor
Lenguaje Objeto
Compiladores
14
Ambiente de compilación
Luego de la generación del código objeto a veces es
necesario importar algunas funciones estándares lo
que significa combinar el código obtenido con otros
previamente almacenados, de manera que se forme
un código ejecutable y se pueda ubicar en la memoria
para su ejecución.
Los encargados de realizar estas funciones son
conocidos como Cargadores y Editores de enlaces.
Compiladores
15
Ambiente de compilación
Fuente
Compilador
Objeto
Cargador
Ed. Enlace
Ejecutable
Compiladores
16
Cargadores y Editores de enlace
Editor de enlace: permite formar un solo programa a
partir de varios archivos de código de máquina
reubicables, ya obtenidos de compilaciones o
almacenados en bibliotecas de rutinas.
Cargadores: Resuelve el problema de direcciones
absolutas y/o programas reentrantes. Tiene como
objetivo ubicar el programa en memoria para su
ejecución.
Compiladores
17
*
Modelo
En el proceso de traducción existen dos tareas básicas:
Análisis
(front-end): El texto de entrada es
examinado, verificado y comprendido.
Generación de Código (back-end): Se genera código
objeto equivalente a la cadena de entrada.
Esto permite que:
Front-end y back-end se comuniquen solo a través de
la representación intermedia.
Front-end
depende sólo del lenguaje fuente
(independe del lenguaje objeto)
Back-end depende exclusivamente del lenguaje objeto
(independe del lenguaje fuente).
Compiladores
*
18
Análisis
Normalmente asociamos la Sintaxis a la idea de
forma, mientras que la Semántica se asocia a
significado o contenido. Así la sintaxis de un lenguaje
debe describir todos los aspectos relativos a la
forma de construcción de programas correctos,
mientras que la semántica debe describir lo que
sucede cuando el programa es ejecutado.
Teóricamente sólo los programas correctos
pertenecen al lenguaje y los programas incorrectos
no tienen interés. Un programa o es del lenguaje
(está correcto) o no es del lenguaje (no está
correcto).
Compiladores
19
Análisis
Pero en la práctica cuando un programa no está
correcto un buen compilador debe indicar este hecho
y tratar de ayudar al usuario a transformalo en un
programa correcto. El tratamiento de errores
incluye mensajes informativos y una recuperación del
error para que el análisis continúe y otros errores
sean detectados.
Normalmente el análisis se divide en léxico,
sintáctico y semántico.
Compiladores
20
Fases de un compilador
Las fases de un compilador son:
Análisis léxico
Análisis Sintáctico
Análisis Semántico
Generación de código
Compiladores
21
Fases de un compilador
Analizador Léxico
Analizador Sintáctico
Administrador de la
tabla de símbolos
Analizador Semántico
Generador de Código
Manejador de
errores
Optimizador de Código
Compiladores
22
Analizador Léxico
Tiene como finalidad la separación e identificación
de los elementos que componen un programa,
igualmente elimina los elementos “decorativos “ como
blancos, comentarios, etc.
Como resultado de este análisis los items como
identificadores, palabras reservadas, operadores,
etc. son reconocidos (comúnmente a través de un
código y una cadena de caracteres).
Compiladores
23
*
Analizador Léxico
Ejemplo:
if x > 0 then
modx := x
{x es positivo}
else
modx := (-x) {x es negativo}
Compiladores
24
Analizador Léxico
Luego del análisis léxico tendríamos la secuencia de
elementos (tokens):
Tipo de token
palabra reservada if
identificador
operador mayor
literal numérico
palabra reservada then
identificador
operador de atribución
Valor del token
if
x
>
0
then
modx
:=
Compiladores
25
Analizador Léxico
Normalmente los tipos de tokens se representan con
valores de un tipo enumerado o con valores
numéricos
Generalmente la implantación de un analizador léxico
(scanner) se basa en un autómata finito que reconoce
las diferentes construcciones.
El análisis léxico puede ser complicado dependiendo
del lenguaje fuente, por ejemplo Fortran no tiene
palabras reservadas, permite el uso de blancos en los
identificadores entre otras características que
hacen que el scanner sea bastante complejo.
Compiladores
26
Analizador Léxico
Ejemplo: DO 10 I = 5
Puede ser el inicio de un comando de asignación
DO 10 I = 5.
Puede ser el inicio de un comando repetitivo
DO 10 I = 5, 10
Note que sólo cuando aparece el . o la ; se sabe con
seguridad que comando estamos analizando.
La mayoría de los lenguajes modernos trata de
simplificar la implantación de los scanners
Compiladores
27
Analizador Sintáctico
También conocido como Parser.
Tiene como finalidad reconocer la estructura global
del programa, verificando que los comandos,
declaraciones, expresiones cumplan con las reglas
de composición (está bien escrito).
Para el programa presentado antes se debería
reconocer que se trata de un <comando>, mas
específicamente de un <comando-if> compuesto de
la palabra reservada if, seguido de una <expresión>,
seguida de la palabra reservada then, etc.
Compiladores
28
*
Analizador Sintáctico
Normalmente las reglas de formación de los
lenguajes se expresan mediante reglas gramaticales
(que se conoce como gramática de un lenguaje)
Existen tipos de gramáticas y a cada uno
corresponde una forma de realizar el análisis
sintáctico, lo que da origen a los diferentes
métodos de parsers.
Un aspecto importante de los analizadores
sintácticos es la recuperación de errores es decir
una vez detectado el error ¿cómo continuar con el
análisis sintáctico?
Compiladores
29
Analizador Sintáctico
Ejemplo: forb I := 1 to 10 do …..;
Si se detecta el error en el identificador forb
seguido de otro identificador I (no es inicio de
ningún comando válido), podemos considerar forb
como error y asumir que I es el inicio de una
asignación; cuando se encuentra la palabra
reservada to nuevamente dará error puesto que
una asignación no contiene esa palabra reservada.
Es claro que seguiremos generando errores (que no
existen) como consecuencia de una palabra
reservada mal escrita y principalmente de una
recuperación no muy correcta.
Compiladores
30
Analizador Semántico
Básicamente el análisis Semántico trata los
aspectos sensibles al contexto de la sintaxis de los
lenguajes de programación. Por ejemplo no se puede
representar en una gramática libre de contexto una
regla como: “todo identificador debe ser declarado
antes de ser usado”, es responsabilidad del análisis
semántico verificar si esa regla se cumplió o no.
En muchos casos un gran apoyo para esta fase es la
denominada Tabla de símbolos
Compiladores
*
31
Analizador Semántico
Se dice que el análisis semántico es dirigido por la
sintaxis: se asocia a cada regla de la gramática una
acción (acción semántica) que será ejecutada cada
vez que se “señala” la regla. Estas acciones son
implantadas frecuentemente como llamadas a rutinas
semánticas y pueden ser responsables por realizar el
análisis semántico y la generación de código.
No existe una frontera definida entre lo que debe
ser tratado por el análisis sintáctico o lo que debe
ser tratado por el análisis semántico, quedando esta
decisión a criterio del diseñador del compilador.
Compiladores
32
Tabla de Símbolos
También conocida como tabla de identificadores
Es una estructura de datos que contiene un registro
por cada identificador del programa (con sus
atributos). Esta estructura permite encontrar
rápidamente el registro para cada identificador y
almacenar o consultar de manera eficiente los
campos dentro de ese registro.
Por
tanto
guarda
información
sobre
los
identificadores (nombre, tipo, ámbito, dirección de
memoria, número de parámetros y tipo si fuera un
nombre de procedimiento, etc.)
Compiladores
33
*
Tabla de Símbolos
Es una tabla muy importante por cuanto apoya a las
diferentes etapas de la traducción.
Su estructura y organización en general depende de
las características del lenguaje fuente.
Compiladores
34
Generación de código
A veces se construye una representación intermedia
del programa fuente para ser usada como base para
la generación del código objeto. Suponiendo que la
forma de ese código intermedio es buena entonces
el proceso de generación de código depende sólo de
la arquitectura de la máquina para la cual el código
será generado.
Las máquinas sencillas ofrecen pocas opciones y eso
implica en un proceso de generación de código más
directo.
*
Compiladores
35
Generación de código
Ejemplo: para la expresión
x := a + b * c
Usando
variables
temporales
para
guardar
operaciones intermedias, podemos generar el
siguiente código, que aunque correcto puede ser
optimizado:
Compiladores
36
Generación de código
Load b
Mult c
Store t1
Load a
Add t1
Store t2
Load t2
Store x
Podemos notar que hay instrucciones no necesarias.
Un código optimizado sería:
Compiladores
37
Generación de código
Load b
Mult c
Add a
Store x
Este tipo de optimización de código se denomina
dependiente de la máquina porque usa las
características de la máquina para optimizar el
código.
Hay optimizaciones que son independientes de la
máquina y cuya preocupación principal es analizar el
programa más que las características de la máquina.
Compiladores
38
Tratamiento de errores
Un problema muy importante que hay resolver en
cualquier fase de un traductor es la recuperación de
errores. Es es: como continuar con el proceso una
vez que se detectó un error de manera tal a no
emitir mensajes de errores no existentes.
Errores léxicos: abre “ y no se cierran
Errores sintácticos: comandos mal escritos
Errores semánticos: variable no declarada.
Compiladores
39
Tratamiento de errores
Se han realizado intentos para tener compiladores
que no sólo se recuperen de un error sino mas bien
traten de corregir los errores para continuar con un
programa sin error que se pueda ejecutar.
No se trata de un problema trivial y se tendrían que
aplicar técnicas de inteligencia artificial
Por ejemplo si tenemos: forb I := 10
¿Cuál fue el error? ¿Variable mal escrita (forbI) o
palabra reservada mal escrita (for)?
Compiladores
40
Descargar