Universidad General Gerardo Barrios
Curso:
Compiladores e Interpretes
Alumno:
Fernando Jose Contreras Lara
Docente:
Marvin Osmaro Parada Benitez
Contenido
Introduccion
Carta de presentacion
Resumen Clase 2
Resumen Clase 3
Resumen Clase 4
Resumen Clase 6
Resumen Clase 7
Resumen Clase 10
Resumen C++
Introduccion
Este portafolio se elabora para llevar un registro y mostrar los temas enseñados y poder mostrar de forma resumida los puntos importantes mostrados en respectiva clase dada.
Cuyos temas se basan en el Compilador viendo sus respectivas partes que le conforman como sus lenguajes.
Carta de Presentacion
Nombre: Fenando Jose Contreras Lara
Genero: Hombre
Edad; 21
Dedicacion; Estudiante
Especialisacion: Ingenieria en sistemas
Objetivo del Curso: poder aprender sobre los compiladores y pasar la materia
Motivo y propósitos del desarrollo del portafolio:
elaborar un resumen del curso en el cual se muestre lo principal o importante aprendido y dejar evidencia de lo enseñado en el curso
Resumen Clase 2
Clase#2 Clasificación de los Interpretes
Concepto de Interprete
• En lugar de producir un programa objeto como resultado de una traducción,
un intérprete realiza las operaciones que implica el programa fuente.
• Un intérprete no genera un programa equivalente, sino que toma una sentencia del programa fuente en un lenguaje de alto nivel,
la traduce al código equivalente y al mismo tiempo la ejecuta.
• Un intérprete es un programa que analiza y ejecuta simultáneamente el programa fuente, es decir no producen un código objeto,
siendo su ejecución simultánea a la del programa fuente.
Ventajas de los Interpretes
• Su principal ventaja es que permiten una fácil depuración. Permiten una mayor interactividad con el código en tiempo de desarrollo.
• En algunos lenguajes (Smalltalk, Prolog, LISP) está permitido y es frecuente añadir código según se ejecuta otro código, y esta característica solamente es posible implementarla en un intérprete.
• Puede ser interrumpido con facilidad.
• Puede ser rápidamente modificado y ejecutado nuevamente
*Un Intérprete necesita menos memoria que un compilador
*Facilita la búsqueda de errores.
*En algunos lenguajes está permitido añadir código según se ejecuta otro código.
*Menor consumo de memoria.
Desventajas de los Interpretes
• Lentitud de ejecución, ya que al ejecutar a la vez que se traduce no puede aplicarse un alto grado de optimización. Cada instrucción debe ser traducida a código máquina tantas veces como sea ejecutada
• Durante la ejecución, el intérprete debe residir en memoria ya que no genera código objeto.
• Tamaño del programa objeto, que exige añadir el intérprete al programa propiamente dicho.
Clasificación de Intérpretes
• Intérpretes Puros
• Interpretes Avanzados
• Interpretes Incrementales
Intérpretes Puros
• Los intérpretes puros son los que analizan una sentencia y la ejecutan, y así sucesivamente todo el programa fuente.
Fueron los intérpretes desarrollados en la primera generación de ordenadores, pues permitían la ejecución de largos programas con ordenadores de memoria muy reducida,
ya que sólo debían contener en memoria el intérprete y la sentencia a analizar y ejecutar.
• El principal problema de este tipo de intérpretes es que si a mitad del programa fuente se producen errores, se debe de reiniciar el proceso.
Interpretes Avanzados
• Los intérpretes avanzados o normales incorporan un paso previo de análisis de todo el programa fuente. Generando posteriormente un lenguaje intermedio que es ejecutado por ellos mismos.
• De esta forma en caso de errores sintácticos no pasan de la fase de análisis.
Interpretes Incrementales
• Algunos lenguajes no se pueden compilar, debido a que entre sus características pueden manejar objetos o funciones que no son conocidos en tiempo de compilación, ya que son creados en ejecución.
Para este tipo de lenguajes existen los intérpretes incrementales, que permiten compilar los módulos completamente definidos, y recompilar en tiempo de ejecución los nuevos módulos.
• Los intérpretes incrementales tienen gran interés en los lenguajes que permiten no definir los problemas completamente en tiempo de compilación.
En estos casos se utilizan evaluadores parciales que toman como entrada el programa fuente junto con algunos datos (pero no todos), realizándose los cálculos que se pueden hacer con dicho subconjunto de datos, y produciendo una salida que contiene un residuo del programa fuente que se ha introducido.
Lo aprendido en esta clase es:
El interprete en vez del compilador este es mucho mas rapido, este traduce a codigo maquina y no genera codigo fuente lo malo es que siempre debe transformar todo a codigo maquina cada vez que se traduce.
Resumen Clase 3
Diferentes puntos de vista para clasificar los lenguajes de programación:
1. Su grado de independencia con la máquina.
2. La forma de sus instrucciones y la forma de procesar el código fuente.
3. Por generaciones.
Los lenguajes de programación según su grado de independencia de la máquina:
a) Lenguaje máquina (representación binaria o hexadecimal.).
b) Lenguaje ensamblador o de bajo nivel (versión simbólica de un lenguaje máquina).
c) Lenguaje de medio nivel (lenguaje C). d) Lenguaje de alto nivel (FORTRAN, COBOL, Pascal).
a) Lenguaje de máquina.
El lenguaje de máquina de una computadora consta de cadenas de números binarios (ceros y unos) y es el único que "entienden" directamente los procesadores.
Todas las instrucciones preparadas en cualquier lenguaje de máquina tienen por lo menos dos partes.
La primera es el comando u operación, que dice a la computadora cuál es la función que va a realizar.
Todas las computadoras tienen un código de operación para cada una de sus funciones. La segunda parte de la instrucción es el operando,
que indica a la computadora donde hallar o almacenar los datos y otras instrucciones que se van a manipular;
el número de operando de una instrucción varía en las distintas computadoras.
b) Lenguaje ensamblador
La comunicación en lenguaje de máquina es particular de cada procesador que se usa, y programar en este lenguaje es muy difícil y tedioso,
por lo que se empezó a buscar mejores medios de comunicación con ésta.
c) Lenguajes de alto nivel Los primeros programas ensambladores producían sólo una instrucción en lenguaje de máquina por cada instrucción del programa fuente.
Para agilizar la codificación, se desarrollaron programas ensambladores que podían producir una cantidad variable de instrucciones en lenguaje de máquina por cada instrucción del programa fuente. Dicho de otra manera,
una sola macroinstrucción podía producir varias líneas de código en lenguaje de máquina
Los lenguajes de programación según su forma de instrucciones
Lenguajes imperativos o procedimentales
Lenguajes declarativos, funcionales o aplicativos
Lenguajes orientados a objetos
Los lenguajes de programación según su forma de procesar el código fuente
Traductores (translators).
Compiladores (compilers). Ensambladores (assemblers).
Interpretes (interpreters). Editores (editors).
Fase de Síntesis:
Etapa de generación de código intermedio
En la etapa de optimización de código
Etapa de generación de código
Análisis Léxico
El analizador léxico lee los caracteres del programa fuente, y verifica que correspondan a una secuencia lógica (identificador, palabra reservada etc.).
Análisis Sintáctico
El analizador sintáctico impone una estructura jerárquica a la cadena de componentes léxicos, generada por el analizador léxico, que es representada en forma de un árbol sintáctico.
Análisis Semántico
El analizador semántico verificara en este caso que cada operador tenga los operandos permitidos.
Generador de código intermedio
Esta etapa se lleva la preposición a una representación intermedia como un programa para una maquina abstracta.
Optimización de código
El código intermedio obtenido es representado de una forma más óptima y eficiente.
Generador de código
Finalmente lleva el código intermedio a un código objeto que en este caso es un código re localizable o código ensamblador (también llamado código no enlazado)
lo que aprendi aqui fue:
Los lenguajes de programacion tienen gradod e independencia de la maquina (binario)
Los lenguajes de programacion se diferencian segun su forma de procesar el codigo fuente
por ejemplo se dividen
Lenguaje maquina
Lenguaje ensamblador
Lenguaje de nivel medio
Lenguaje de alto nivel
Fase de sistencis se deriba en
Etapa de generación de código intermedio
En la etapa de optimización de código
Etapa de generación de código
Resumen Clase 4
TABLA DE SÍMBOLOS
Almacena todos los nombres declarados en el programa y sus atributos (tipo, valor, dirección, parámetros, etc.).
Se usa en las distintas fases del compilador
Estructura de datos.
Almacena información sobre:
Los identificadores.
Las palabras reservadas.
Las constantes.
Por cada entrada en la tabla de símbolos habrá que guardar:
• Lexema correspondiente.
• Tipo. (depende de la implementación)
• Ámbito. (depende de la implementación)
• Dirección de memoria asignada.
• Forma. (depende de la implementación)
¿UTILIDAD DE LA TABLA DE SÍMBOLOS?
Analizador Léxico: Pasa en el token y la entrada de la TS creada.
Analizador Sintáctico y Semántico: Busca el token y si no lo encuentra crea una nueva entrada
DATOS QUE SE ALMACENAN:
Para un array:
• Tipo de los elementos.
• Número de elementos. • Límites inferior y superior.
Para una función:
• Número de parámetros. • Tipo de los parámetros. • Forma de paso de parámetros.
• Tipo de retorno
OPERACIONES PRINCIPALES
Insertar: introduce un símbolo tras una declaración.
Buscar: recupera información asociada a un símbolo.
Eliminar: borra la información de un símbolo cuando ya no se utiliza
EJEMPLOS DE USO II
Acceso a una posición de un array: – Declaración
> Inserción en la TS – Acceso a un array
> Búsqueda en la TS
1. Comprobación de tipo array
2. Comprobación acceso a una posición válida
lo que he aprendido es:
La tabla de simbolos por cada una se guarda el lexema correspondiente. tipo, direccion y forma
y sus operaciones principales son insertar, borrar y elminar
Resumen Clase 6
Analisis lexico
Está constituido por todas las palabras y símbolos que lo componen.Para un lenguaje de programación la definición también es válida.
- Lo constituyen todos los elementos individuales del lenguaje, denominados frecuentemente en inglés tokens
Token
Así son tokens: las palabras reservadas del lenguaje, los símbolos que denotan los distintos tipos de operadores, identificadores (de variables, de funciones, de procedimientos, de tipos, etc.), separadores de sentencias y otros.
Token
Elemento léxico del lenguaje ? Símbolo No Terminal de las fases siguientes
Patrón
Expresión regular que define el lenguaje ? Letra (Letra | Digito)
Lexema
Secuencia de caracteres que concuerda con un patrón
Numero, caracter.
Atributos
Estructura de datos de cada token para almacenarse en la TS
Depende del tipo de token
[ID, Lexema, Tipo, Valor, línea]
lo que aprendi aqui es:
que el analisador lexico esta conformados por tokens, lexema y atributos
Resumen Clase 7
Análisis semántico
Que es la semántica?
Se refiere a los aspectos del significado, sentido o interpretación del significado de un determinado elemento, símbolo, palabra, expresión o representación formal.
Análisis semántico
Se trata de determinar el tipo de los resultados intermedios, comprobar que los argumentos que tiene un operador pertenecen al conjunto de los operadores posibles, y si son compatibles
entre sí, etc. En definitiva, comprobará que el significado de lo que se va leyendo es válido.
Análisis semántico
El análisis semántico se realiza posteriormente al sintáctico y mucho más difícil de formalizar que éste.
Que es un árbol semántico?
Es una estructura jerárquica en la cual se registran las operaciones que implica u operan dentro del programa fuente En cada una de las ramas del arbol semantico se registra el
valor o significado que este debe tener, y el analisis semantico se encarga de terminar cual de los valores registrados en las ramas es aplicable.
Tabla de símbolos en esta fase
Un compilador necesita guardar y usar la información de los objetos que se va encontrando en el texto fuente, como variables, etiquetas, declaraciones de tipos, etc.
Esta información se almacena en una estructura de datos interna conocida como tabla de símbolos.
El compilador debe desarrollar una serie de funciones relativas a la manipulación de esta tabla como consultar un elemento en ella, y consultar la información relacionada con un símbolo, etc.
Como se tiene que acceder mucho a la tabla de símbolos los accesos deben ser lo más rápidos posible para que la compilación sea eficiente.
Sistemas de tipo:
Es el conjunto de reglas que determinan el criterio para asignar expresiones de tipo a las diferentes partes del código fuente.
? Tipo básico: entero, carácter, real, lógico ? Nombres de tipo ? Constructores de tipo: estructuras, uniones, objetos ? Apuntadores: referencias a tipos ? Funciones a=suma();
Chequeos de tipos (y otros)
Un compilador debe realizar una serie de chequeos estáticos, como chequeos de tipos:
Consistencia: unicidad, existencia, no-ciclicidad, ... Equivalencia y compatibilidad de tipos Inferencia de tipos (en valores) Sobrecarga de funciones y operadores
COMPROBACIONES SEMÁNTICAS TIPOS
Comprobaciones ESTÁTICAS. Las comprobaciones sintácticas y semánticas. Comprobaciones DINÁMICAS. Realizadas en tiempo de ejecución.
COMPROBACIONES SEMÁNTICAS TIPOS
Comprobaciones SEMÁNTICAS
De TIPO.
Verificación del tipo de los operando en las expresiones.
De FLUJO de CONTROL.
Verifica los puntos del programa de salida y entrada del control.
De UNICIDAD. Verifica la presencia de símbolos de forma única. (ejemplo: declarar un símbolo una sólo vez).
Relación de NOMBRES. Un mismo nombre puede aparecer más de una vez.
lo que aprendi es:
que el analisis semantico revisa que los comandos esten bien escrito y ver
si existe en el lenguaje el comando escrito.
La tabla de simbolos de fase revisa que cada simbolo y compara con lo ya guardado
siendo como variables por ejemplo, y esta accion debe ser rapida para que el compiilador sea eficiente.
Resumen Clase 10
INDEPENDENCIA DE LA MÁQUINA
Según el modelo de arquitectura de un compilador en el que éste se divide en frontend y backend,
la etapa inicial traduce el programa fuente a una representación intermedia a partir de la cual la etapa final genera el código objeto,
ya sea en forma de código máquina o ensamblador
La construcción del lenguaje objeto en la etapa final,
facilita la reutilización del frontend para crear otros compiladores del mismo lenguaje pero que generan código para otras plataformas.
La división en etapas se realiza utilizando un código intermedio independiente de la máquina destino.
El programa en código intermedio resultante es la salida de la etapa frontend y la entrada al backend
El código intermedio es una simplificación de los lenguajes de alto nivel en la que se elimina las estructuras y las declaraciones y con sentencias cercanas al ensamblador.
El código intermedio se utiliza en un compilador por las siguientes razones:
1. Es mas fácil hacer la conversión en dos fases. 2. Independiza el analizador sintáctico del resto del compilador.
Es mas sencillo aplicar la optimización sobre instrucciones independientes del hardware que sobre instrucciones dependientes
Los lenguajes intermedios son representaciones abstractas de un leguaje fuente. Algunas representaciones obsoletas o en desuso son los árboles sintácticos.
Actualmente se utilizan como código intermedio las cuádruplas.
Tipos de cuádruplas:
Cuartetos o código de tres direcciones (OPERADOR, operando1, operando2, resultado)
Tercetos o código de dos direcciones. (OPERADOR, operando1, operando2)
Lo que entendi en esta clase fue:
Según el modelo de arquitectura de un compilador en el que éste se divide en frontend y backend
que mediante traducciones al final genera un codigo objeto siendo de maquina u ensamblador
el codigo intermedio se utiliza en un compilador porque es mas facil hacer la conversion en dos fases e independisa el analizador
sintactico del resto del compilador
Resumen C++
Es un lenguaje de programación creado por Bjarne Stroustrup en los laboratorios de At&T en 1983.
Un programa en C++ está definido por funciones (grupo de instrucciones que pueden o no hacer algún cálculo), donde la función principal debe ser llamada main.
La composición general de un programa en C++ es:
directivas de preprocesamiento. declaración globales. función main. funciones definidas por el usuario. comentarios para entender el funcionamiento del programa.
En particular, en C la directiva para incluir bibliotecas es como las siguientes: Ejemplos: #include <iostream.h>
Esta directiva permitirá utilizar la función de lectura cin y la función de escritura cout propias de C++. #include <stdio.h> Esta directiva permitirá utilizar las funciones de lectura y escritura propias de C.
Estas directivas también funcionan con C++, aunque existen algunos compiladores que no las soportan en cuyo caso es necesario hacer uso de los namespaces.
Un namespace es una declaración de región. El propósito de estos es localizar el nombre de identificadores para evitar colisiones.
Para tener compatibilidad, cuando un programa en C++ incluye una librería de C, haremos uso del namespace.
Ejemplo: En C tenemos #include <iostream.h>
Con el respectivo en C++ #include <iostream> using namespace std;
Las declaraciones globales son definiciones de variables o constantes que serán utilizadas por cualquiera de todas las funciones definidas en el programa.
La sintaxis para la declaración de una variable es: Tipo var1, var2,..., var3;
o bien Tipo var1= valor, var2,..., var3;
La función main( ), es obligatoria en cada programa C, C++.
Indica el comienzo del programa y requiere los paréntesis ( ) a continuación de main( ).
La definición de una función se realiza escribiendo primero el tipo del valor de retorno de la función, después el nombre de la función, posteriormente entre paréntesis las variables que utilizará dicha función (parámetros) y finalmente las instrucciones de la función. Ejemplos:
double promedio( int a, int b, int c) { return (a + b + c ) / 3.0; }
Declara a la función promedio, la cual recibe tres valores enteros y calcula y regresa el promedio de ellos.
Los comentarios pueden escribirse utilizando alguna de las siguientes formas:
1. comentando en la misma línea, utiliza //, ejemplo
int edad; // la edad se utilizará como un valor entero.
2. comentando entre varias líneas, utiliza /* */, ejemplo:
/* La siguiente función promedio recibe tres valores enteros
y calcula y regresa el promedio de los tres a través
de un valor real */
Se utiliza el tipo char. Para representar un carácter en C++ se utilizan apóstrofes.
Ejemplos: ‘a’, ‘b’ , ‘5’
Para representar una cadena de caracteres se utilizan las comillas.
Ejemplo: “soy una cadena”
El archivo de cabecera iostream.h de la biblioteca de C++ proporciona un flujo de salida estándar cout y un operador de extracción <<, que normalmente se manda a la pantalla del usuario.
Sintaxis del estatuto cout
cout << Lista;
donde Lista puede ser variables, valores constantes o expresiones separadas por <<
Ejemplos:
cout << "Dame el numero "; // estamos desplegando el mensaje
// en pantalla.
cout << "El resultado es " << resul; // estamos desplegando el
// mensaje y el valor de la
// variable resul.
Los operadores de extracción e inserción, >> y <<, apuntan en la dirección del flujo de datos. Recordemos que para poder utilizar el estatuto cin y cout se requiere la directiva #include <iostream>.
Existen caracteres especiales que pueden ser usados con el cout dentro de comillas. Entre ellos están:
\ n realiza un cambio de línea equivalente a usar endl.
\ t tabulador.
\ a sonido de la campana.
\ “ comilla doble.
\ ‘ comilla simple.
La declaración de una variable es un estatuto que proporciona información de la variable al compilador de C++.
La sintaxis para la declaración de una variable es: tipo variable tipo.- es el nombre de un tipo de dato conocido por C++. variable.- es un identificador (nombre) válido en C++.
Deben empezar con letra o underscore
Pueden contener letras, números y underscore
Las letra mayúsculas y minúsculas son diferentes para C++
Ejemplos:
int x; // declara el nombre de la variable x de tipo entero.
char var; // declara var de tipo carácter.
int i = 0; // define i inicializa la variable i entera a cero.
Funciones definidas por el usuario
Un programa en C++ se forma por una colección de funciones.
Todos los programas se construyen a partir de una o más funciones que se integran para crear una aplicación.
Todas las funciones contienen uno o más estatutos C++ y se crean generalmente para realizar una única tarea.
Por ejemplo:
double promedio( int a, int b, int c)
{ return (a + b + c ) / 3.0;
}
Declara a la función promedio, la cual recibe tres valores enteros y calcula y regresa el promedio de ellos
En este apartado logre entender un poco lo básico y necesario para poder usar C++ ya que es el lenguaje con el que se trabaja
Lo que aprendí de esto fue:
El lenguaje c++ es un lenguaje muy usado el cual esta definida por funciones por ejemplo tenemos main, C++ tiene declaraciones globales, al igual que puede incluir bibliotecas como #include <iostream.h> .Tambien hay directivas que funsionan con c++ aunque haigan compiladores que no la soporten en los cuales se usa el namespace. La función main( ), es obligatoria en cada programa C, C++. Indica el comienzo del programa y requiere los paréntesis ( ) a continuación de main( ), al igual se pueden incluir comentarios en medio del codigo para dar un poco de información sobre que podría consistir cada parte
Conclusion:
al ver el amplio contenido visto se puede apreciar que se a indagado en muchos temas y detalles y aun mas en el contenido completo del cual se basa ese portafolio digital, aunque el gran contenido se haya puesto en practica no siempre se puede aprender a la primera mas con la complejidades de algunos temas tocados como los lenguajes de programacion y los complejos compiladores los cuales le conforman los diferentes lenguajes que tienen un importante propósito, esto da a caber que al ser un tema interesante no es algo que se a[renda a primera pero con una buena orientacion y practica es posible lograr dominarlo
No hay comentarios:
Publicar un comentario