Está en la página 1de 21

INSTITUTO TECNOLOGICO DE SALTILLO

NOMBRE DE LA MATERIA:
LENGUAJES DE AUTÓMATAS 2

PROYECTO INTEGRADOR

NOMBRE DEL DOCENTE:


Ing. KARINA CABRERA CHAGOYÁN

ESTUDIANTE:
GISEL ALEJANDRA RODARTE RIVERA

CARRERA: INGENIERÍA EN SISTEMAS


COMPUTACIONALES

HORA: 10:00-11:00 PM
Introducción
La materia de Lenguajes y autómatas 2 presta especial importancia a los
compiladores, más precisamente a las etapas que deben de realizarse para la
creación de uno.
En este proyecto mostraremos todo lo aprendido durante el semestre en la clase
de lenguajes y autómatas, se explicaran las fases de la generación de código
intermedio y el código objeto, así como las prácticas realizadas a lo largo del
semestre para demostrar lo aprendido.

Formulación del problema


Simular las etapas de generación de código intermedio y ejecución para un
lenguaje de prueba.

Objetivo
Demostrar el desarrollo y alcance de las competencias de la asignatura.
Descripción del proyecto

Marco teórico
Código intermedio

El código intermedio es un código abstracto independiente de la máquina para la


que se generara el código objeto. Sirve para eliminar la necesidad de un nuevo
compilador completo para cada máquina de la sección de análisis mismo de todos
los compiladores.

En el proceso de traducir un programa fuente a código destino, un compilador


puede construir una o más representaciones intermedias, las cuales pueden tener
una variedad de formas. Los árboles sintácticos son una forma de representación
intermedia; por lo general, se utilizan durante el análisis sintáctico y semántico.

Después del análisis sintáctico y semántico del programa fuente, muchos


compiladores generan un nivel bajo explícito, o una representación intermedia
similar al código máquina, que podemos considerar como un programa para una
máquina abstracta. Esta representación intermedia debe tener dos propiedades
importantes: debe ser fácil de producir y fácil de traducir en la máquina destino.

Notación sufija y cuádruplas

La notación sufija es en la que el operador ocupa la posición después de los


operados, Una cuádrupla es una estructura de tipo registró con cuatro campos:
operación, resultado, argumento1 y argumento2.

Código de 3 direcciones

Consiste en una secuencia de instrucciones, cada una de las cuales tiene como
máximo tres operandos, Se le llama de esa forma porque solo permite referenciar
a 3 direcciones de memoria al mismo tiempo. Esto significa que expresiones
como (a+3)*(4-5)/2 no pueden ser operadas como una sola instrucción. Por lo
tanto se debe descomponer la expresión en expresiones más sencillas.
Preparación para la generación de código
El módulo de generación de código de un compilador tiene por objeto generar el
código equivalente al programa fuente escrito en un lenguaje diferente. En función
del tipo de lenguaje objetivo, se distinguen distintos tipos de compiladores:

•Cross-compilers (compiladores cruzados): traducen de un lenguaje de alto


nivel a otro lenguaje de alto nivel.

•Compiladores que generan código en lenguaje simbólico: generan un código


intermedio que después deberá ser procesado por un ensamblador.

•Compiladores que generan código en lenguaje de la máquina: generan


directamente programas ejecutables (*.EXE) especial de código máquina
(*.OBJ) que contiene información adicional, y que después será procesado
por un programa enlazador que generará el programa ejecutable a partir de uno o
más programas en formato OBJ, algunos de los cuales pueden estar contenidos
en bibliotecas que suelen proporcionarse junto con el compilador, y que contienen
funciones y subrutinas prefabricadas de uso general.

Generación de código de sentencias de control u expresiones


lógicas

El código generado por la comparación almacena en los indicadores el valor true o


false, según corresponda, encendiendo o apagando uno de los indicadores. En
tal caso, la instrucción condicional sólo tendría que generar la siguiente instrucción
en la acción semántica situada en la regla justo a continuación de la unidad
sintáctica then:jz fin_then donde fin_then es una etiqueta interna generada por el
compilador. Por otra parte, la acción semántica, situada al final de la regla,
generaría el siguiente código:fin_then#: Es decir, colocaría la etiqueta después
del código generado por el símbolo no terminal.

Tipos de compiladores

Ensamblador: el lenguaje fuente es lenguaje ensamblador y posee una estructura


sencilla.

Compilador cruzado: se genera código en lenguaje objeto para una maquina


diferente de la que se está utilizando para compilar.

Compilador con montador: compilador que compila distintos módulos de forma


independiente y después es capaz de enlazarlos.
Autocompilador: compilador que está escrito en el mismo lenguaje que va a
compilar.

Metacompilador: compilador de compiladores y se requiere a un programa que


recibe como entrada las especificaciones del lenguaje para el que se desea
obtener un compilador y genera como salida el compilador para ese lenguaje.

Descompilador: es un programa que acepta como entrada código máquina y lo


traduce a un lenguaje de alto nivel.

Generación de código maquina

Es la traducción de la representación intermedia a código objeto, hay que tener en


cuenta la arquitectura de la máquina para realizar una gestión eficiente de la
memoria y de los registros. Para esto primero se generan las directivas para
reservar memoria para las variables y datos, luego se genera el resto del código.

¿Qué es ensamblador, enlazador y cargador?

Ensamblador se refiere a un programa que se encarga de desestructurar el código


en lenguaje ensamblador y traducirlo a lenguaje binario.

Los enlazadores son los programas que enlazan varios ficheros objeto en lenguaje
binario para crear un único fichero, el cual será el ejecutable del programa.

Un cargador es un programa que coloca en la memoria para su ejecución, el


programa guardado en algún dispositivo de almacenamiento secundario.

Interprete
Es un procesador de lenguaje que analiza un programa escrito en un lenguaje de
alto nivel y, si es correcto, lo ejecuta directamente en el lenguaje de la máquina en
que se está ejecutando el intérprete. Cada vez que se desea ejecutar el programa,
es preciso interpretar el programa de nuevo.

Código objeto
El generador de código objeto puede considerarse como la penúltima fase de un
compilador, la cual se encarga de tomar como entrada el código intermedio
generado por el front-end, y producir código objeto de la arquitectura objetivo para
luego entrar en la fase de optimización de código. Este código se crea al traducir
el código fuente a uno en lenguaje máquina, que crea un ejecutable al pasar por
un enlazador. Suele tener errores y estos se eliminan en la fase de optimización,
con el código ya optimizado es posible realizar copias e instalar en dispositivos
compatibles.

Optimización
Es un programa de transformación técnica, que trata de mejorar el código, por lo
que consumen menos recursos (es decir CPU, memoria) y ofrecer una alta
velocidad.
En la optimización de alto nivel general de programación son sustituidos por
construcciones muy eficientes de bajo nivel a los códigos de programación
Un código proceso en fase de optimización debe seguir las tres normas:
- El código de salida no debe, de ninguna manera, cambiar el sentido del
programa.
- Optimización debe aumentar la velocidad del programa y si es posible, el
programa debe exigir menos cantidad de recursos.
- Optimización debe ser rápido y no debe retrasar el proceso de compilación
general.
Si bien esta etapa puede considerarse opcional, es recomendado que se realice
para evitar futuros problemas y falta de eficiencia.
Resultados

Primera parte del programa generación del VCI


La primer parte fue la generación de código intermedio en este caso nosotros
creamos un programa en lenguaje java en netBeans, la primer parte del programa
que creamos fue uno que leía un archivo de texto y nos mostraba el VCI de ese
mismo archivo de texto.

Ejecución de la primer parte del programa


En la imagen anterior se puede ver el archivo de entrada de texto y la salida en el
programa, para la entrada de texto usamos el método llamado buffered reader el
cual lee un archivo de texto línea por línea y así poder llamar un documento de
texto ajeno a la aplicación.
De entrada, el programa lee un archivo .txt escrito por el usuario, este contiene la
expresión que será analizada y procesada por la aplicación en código intermedio.
De salida el programa realiza un acomodo del vector de código intermedio a partir
de las prioridades establecidas y lo muestra en la consola, cada valor separado
por “|” para representar del vector escrito de izquierda a derecha.
Explicación de la primer parte del código del programa

Imagen 1.
En primer lugar en la imagen 1 se puede ver como se crean las pilas en donde se
almacenarán los operadores, estatutos y direcciones, además creamos un array llamado
prioridad el cual tiene todos los símbolos y palabras reservadas, seguido de esto se
definen las prioridades de cada símbolo o palabra reservada
Las prioridades que usaremos son las siguientes:

Operador Prioridad
*/ 60
+- 50
<>= 40
NOT 30
AND 20
OR 10
= 0
.

Imagen 2.
En la imagen 2 podemos ver que se realiza un ciclo que lee el arreglo y se establecen las
reglas que seguirá el programa respecto a las prioridades y el uso de las pilas
previamente creadas.

Leemos el archivo de texto con el buffered reader y con el método Split separamos
cada palabra del archivo y la guardamos en un nuevo array.
Después empezamos a recorrer el array de cadena y lo comparamos con el array
de prioridad si hay coincidencia entra en alguna condición y ejecuta su código, si
no la hay imprime directamente el valor de la cadena en el VCI.
Imagen 3.
Por último en la imagen 3 podemos observar que se le indica al programa cómo
imprimirá el vector de código intermedio, indicando que iniciará con el símbolo “|” y
que se repetirá después de cada valor que se llegue a imprimir en consola.
Segunda parte del programa mostrando los movimientos de la pila
La segunda parte del programa consistió en mostrar además del VCI los
movimientos que se hacían dentro de la pila de operadores y como se debían
seguir todas las reglas vistas en clase, lo que hicimos fue usar nuestro primer
programa ya creado y mejorarlo con las cosas que se nos pedían.

Archivo de texto.

Para el programa usaremos como entrada un archivo de texto llamado entradavci,


en la imagen anterior se puede ver lo que contiene el archivo de texto.
Salida 1.

Salida 2.
En las imágenes anteriores nos muestra primero en la salida 1 lo que sería el VCI
del archivo de texto, después un pequeño mensaje y a continuación los
movimientos de la pila, en la imagen salida 2 solo están los movimientos faltantes
de la pila que no alcanzaron a mostrarse en la primera imagen.
Nosotros hicimos que al mostrar los movimientos de la pila lo hiciera cada vez que
detecta una “palabra o letra” nueva en este caso inicia con if y por tanto la pila de
operadores está vacía, por esa razón al principio muestra un mensaje diciendo
que está vacía, después el paréntesis si ingresa a la pila y lo mostramos junto con
su valor de prioridad, en los siguientes movimientos como la x la pila no tiene
ningún cambio por eso se vuelve a repetir el paréntesis, al llegar >= simplemente
entra la pila al ser de prioridad mayor y cuando llega el && vemos que al ser
menor prioridad lo primero que hace es sacar de la pila a >= y después entra el &&
y así continua con las demás reglas en los movimientos restantes.
Explicación de la segunda parte del programa
Como usamos la primer parte del programa realmente no tuvimos tantos
problemas en la lógica de lo que sería las reglas del VCI, sin embargo tuvimos que
ver como mostrar la pila y se mostraran sus pasos.

Código agregado 1.
Para eso lo que hicimos fue crear un for para que hiciera 2 veces la ejecución del
código, la primera vez para que muestre el VCI y la segunda para que nos
muestre los movimientos de la pila ya que en teoría realizaría el mismo
procedimiento que hizo en el paso anterior como se puede ver en la imagen de
código agregado 1.
Además de eso a lo largo del código agregamos varios if como es el caso que se
ve en la imagen de código agregado 1 y 2, donde solo ejecutara ese comando si
va en la segunda vuelta, de esa forma nos aseguramos que solo ejecute ciertas
partes que queremos dependiendo de la vuelta en la que estemos.

Código agregado 2.
En la imagen de codigo agregado 2 podemos ver que es donde mostramos los
valores de nuestra pila, en este caso sería op y “prio” sería una variable que
contiene el valor de la prioridad de cada símbolo, además de mostrar cuando la
pila este vacía. Aunque pareciera que no agregamos mucho código la verdad es
que resulto complicado el analizar cómo llegar a mostrar la pila ya que nos
encontramos con diferentes problemas a lo largo en que se nos ocurrían cosas y
veíamos que unas cosas servían y otras no, al final llegamos como resultado a
esto.
Cabe mencionar que además de esto agregamos más código en el programa
donde poníamos ciertas condiciones para que ciertas partes del código se
ejecutaran solo en la primer o en la segunda vuelta, además de que agregamos la
nueva pila op y su código correspondiente para que funcionara de acuerdo a las
reglas del VCI pero como es prácticamente lo que hicimos en la practica 3 no lo
incluimos en esta parte.

Bibliografía
Desconocido. (2009). Generación de código. 18/06/2021, de Universitat Jaime
Sitio web: https://www3.uji.es/~vjimenez/AULASVIRTUALES/PL-0910/T5-
GENERACION/codigo.apun.pdf
Blanca Rodriguez. (2010). Código intermedio. 18/06/2021, de slideshare Sitio web:
https://es.slideshare.net/blankardz/cdigo-intermedio-5717987
Desconocido. (S.F.). Teoría de Lenguajes y Compiladores. 18/06/2021, de google
sites Sitio web:
https://sites.google.com/site/teoriadelenguajesycompiladores/procesadores-de-
lenguaje/generacion-de-codigo
Desconocido. (S.F.). Compilador Diseño - Generación de Código Intermedio.
18/06/2021, de turorialspoint Sitio web:
https://www.tutorialspoint.com/es/compiler_design/compiler_design_intermediate_
code_generations.htm
Desconocido. (S.F.). Generación de código intermedio. Optimización. 18/06/2021,
de Anónimo Sitio web:
https://hopelchen.tecnm.mx/principal/sylabus/fpdb/recursos/r97350.PDF
Juan Carlos Olivares Rojas. (S.F.). Unidad VI Generación de Código Intermedio.
18/06/2021, de Secretaria de educación pública Sitio web:
http://dsc.itmorelia.edu.mx/~jcolivares/courses/ps207a/ps2_u6.pdf
Compiladores e intérpretes: teoría y practica,Manuel Alfonseca Moreno, Marina de
la Cruz Echeandia, Alfonso Ortega de la Puente, Estrella Pulido Cañabate, Ed.
Pearson Prentice Hall
Desconocido. (S.F.). Unidad II: Análisis semántico. 18/06/2021, de Anónimo Sitio
web: http://itpn.mx/recursosisc/7semestre/leguajesyautomatas2/Unidad%20II.pdf
Anexos
Código completo del programa

También podría gustarte