Tema: Generación de código

Anuncio
Compiladores. Guía 9
1
Facultad:
Ingeniería
Escuela:
Computación
Asignatura: Compiladores
Tema: Generación de código
Contenido
En esta guía se abordarán los conceptos pertenecientes
al componente de generación de código, se implementara
un generador de código en lenguaje C++ para el
compilador del lenguaje MUSIM/3.
Objetivos Específicos



Conocer las características y principal función de
un generador de código.
Analizar el funcionamiento, entrada y salida de un
generador de código de un compilador.
Implementar un generador de código para el lenguaje
MUSIM/3.
Material y Equipo


Guía de Laboratorio Nº 9.
Computadora con programa Dev C++
Introducción Teórica
Generación de código.
Guía 3
Entrada al generador de código:
La
entrada
para el generador de código consta de la
Guía
4
representación intermedia del programa fuente producida por
la etapa inicial junto con la información de la tabla de
fía
símbolos
que se utilizan para determinar las direcciones de
los objetos de datos durante la ejecución denotados por los
hombres de la representación intermedia.
2
Compiladores. Guía 9
• Representaciones lineales:
Tercetos
Cuartetos.
Máquinas a pila.
• Representaciones arborescentes:
Árboles de análisis sintácticos.
Grafos dirigidos a cíclicos.
Programas objeto:
La salida del generador de código es un código preparado y
adaptado para ser ejecutado, directa, o indirectamente, en
una arquitectura específica. La adaptación consiste en
aprovechar al máximo las características de la máquina para
optimizar la ejecución en tiempo y en memoria.
Lenguaje de máquina absoluto:
El programa se coloca en una posición fija de memoria y se
ejecuta inmediatamente. Un programa pequeño se puede compilar
y ejecutar rápidamente pero demanda ubicaciones específicas
de memoria.
Lenguaje de máquina reubicable:
Un programa reubicable permite que los subprogramas se
compilen por separado. Los módulos se cargan y enlazan
mediante un montador o enlazador. Se gana flexibilidad al
poder compilar subrutinas por separado y llamarlas desde
otros módulos. Si la máquina objeto no maneja reubicación
automática el compilador debe proporcionar al montador
información para que enlace los segmentos del programa.
Lenguaje Ensamblador:
El lenguaje ensamblador facilita el proceso de generación de
código (se utilizan instrucciones simbólicas y macros). A
cambio debe producirse un ensamblado tras la generación de
código. Esto es útil en arquitecturas con poca memoria.
Administración de la Memoria:
Uno de los propósitos de la generación de código final es la
traducir la representación simbólica en código intermedio de
etiquetas
y
objetos
de
datos
(variables,
temporales,
parámetros, etc.) a direcciones reales en el mapa físico de
memoria.
Compiladores. Guía 9 3
Asignación de Registros:
Las instrucciones que operan con registros son más cortas y
rápidas. Realizar un uso eficiente de los registros es
fundamental para generar buen código.
Selección de instrucciones:
La generación de código intermedio debe tener en cuenta el
juego
de
instrucciones
de
la
máquina
destino.
Las
traducciones a código objeto debe ser, además de correcta,
eficiente.
Procedimiento
baserrrg
En esta guía vamos a implementar el generador de código para
nuestro proyecto del compilador MUSIM/3 a ENSAMPOCO, para
Guíacrearemos
3
ello
un archivo en C++ de cabecera o extensión “.h”
que contendrá la clase que corresponderá a nuestro generador
de código.
Guía 4
Primero
debe
buscar
su
proyecto
de
este
compilador
actualizado
con el analizador semántico de la guía anterior
fía
4
Compiladores. Guía 9
(procedimiento guía 8). Abra el programa “Dev C++” y abra el
respectivo archivo de proyecto que tiene creado previamente
(poseerá una extensión de archivo “.dev”). Posteriormente,
añada al proyecto
un archivo fuente. Luego digite
el
siguiente código:
genera.h
#ifndef GENERA_H
#define GENERA_H
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
class GeneraCodigo
{
char *nombreFichero; // Nombre del fichero objeto de salida
FILE *salida; // Fichero objeto de salida
public:
GeneraCodigo(char *unNombreFichero);
~GeneraCodigo();
void code();
void pushc(char *constante);
void pusha(char *tipo,char direccion);
void load(char *tipo);
void store(char *tipo);
void neg(char *tipo);
void add(char *tipo);
void mul(char *tipo);
void div(char *tipo);
void mod(char *tipo);
void input(char *tipo,char direccion);
void output(char *tipo,char direccion);
void end();
void abs(char *tipo);
void data();
void declaracion(char tipo, char *id);
void i2tof();
void itof();
void ipushc(char *constante);
void exp(char *tipo);
void sin(char *tipo);
void tan(char *tipo);
};
GeneraCodigo::GeneraCodigo(char *unNombreFichero)
{
if ((salida=fopen(unNombreFichero,"w"))==NULL)
{
Compiladores. Guía 9 5
cout<<"No
se
puede
crear
fichero"<<unNombreFichero<<endl;
exit(-3);
}
}
GeneraCodigo::~GeneraCodigo(void)
{
fclose(salida);
}
void GeneraCodigo::code()
{
cout<<".CODE"<<endl;
fputs(".CODE\n",salida);
}
void GeneraCodigo::pushc(char *constante)
{
cout<<"PUSHC "<<constante<<endl;
fputs("PUSHC ",salida);
fputs(constante,salida);
fputs("\n",salida);
}
void GeneraCodigo::pusha(char *tipo,char direccion)
{
cout<<tipo<<"PUSHA "<<direccion<<endl;
fputs(tipo,salida);
fputs("PUSHA ",salida);
fputc(direccion,salida);
fputc('\n',salida);
}
void GeneraCodigo::load(char *tipo)
{
cout<<tipo<<"LOAD"<<endl;
fputs(tipo,salida);
fputs("LOAD\n",salida);
}
void GeneraCodigo::store(char *tipo)
{
cout<<tipo<<"STORE"<<endl;
fputs(tipo,salida);
fputs("STORE\n",salida);
}
void GeneraCodigo::neg(char *tipo)
{
cout<<tipo<<"NEG"<<endl;
fputs(tipo,salida);
fputs("NEG\n",salida);
}
el
6
Compiladores. Guía 9
void GeneraCodigo::add(char *tipo)
{
cout<<tipo<<"ADD"<<endl;
fputs(tipo,salida);
fputs("ADD\n",salida);
}
void GeneraCodigo::mul(char *tipo)
{
cout<<tipo<<"MUL"<<endl;
fputs(tipo,salida);
fputs("MUL\n",salida);
}
void GeneraCodigo::div(char *tipo)
{
cout<<tipo<<"DIV"<<endl;
fputs(tipo,salida);
fputs("DIV\n",salida);
}
void GeneraCodigo::mod(char *tipo)
{
cout<<tipo<<"MOD"<<endl;
fputs(tipo,salida);
fputs("MOD\n",salida);
}
void GeneraCodigo::input(char *tipo,char direccion)
{
cout<<tipo<<"INPUT "<<direccion<<endl;
fputs(tipo,salida);
fputs("INPUT ",salida);
fputc(direccion,salida);
fputc('\n',salida);
}
void GeneraCodigo::output(char *tipo,char direccion)
{
cout<<tipo<<"OUTPUT "<<direccion<<endl;
fputs(tipo,salida);
fputs("OUTPUT ",salida);
fputc(direccion,salida);
fputc('\n',salida);
}
void GeneraCodigo::end()
{
cout<<"END"<<endl;
fputs("END\n",salida);
}
void GeneraCodigo::abs(char *tipo)
{
Compiladores. Guía 9 7
cout<<tipo<<"ABS"<<endl;
fputs(tipo,salida);
fputs("ABS\n",salida);
}
void GeneraCodigo::data()
{
cout<<".DATA"<<endl;
fputs(".DATA\n",salida);
}
void GeneraCodigo::declaracion(char tipo, char *id){
switch (tipo) {
case 'I':
cout<<"INT "<<id<<endl;
fputs("INT ",salida);
fputs(id,salida);
fputs("\n",salida);
break;
case 'F':
cout<<"FLOAT "<<id<<endl;
fputs("FLOAT ",salida);
fputs(id,salida);
fputs("\n",salida);
break;
case 'C':
cout<<"CHAR "<<id<<endl;
fputs("CHAR ",salida);
fputs(id,salida);
fputs("\n",salida);
break;
default:
cout<<"Tipo desconocido error\n";
exit(-(100));
}
}
void GeneraCodigo::i2tof()
{
cout<<"I2TOF"<<endl;
fputs("I2TOF\n",salida);
}
void GeneraCodigo::itof()
{
cout<<"ITOF"<<endl;
fputs("I2TOF\n",salida);
}
void GeneraCodigo::ipushc(char *constante)
{
cout<<"IPUSHC "<<constante<<endl;
8
Compiladores. Guía 9
fputs(constante,salida);
fputs("\n",salida);
}
void GeneraCodigo::exp(char *tipo)
{
cout<<tipo<<"EXP"<<endl;
fputs(tipo,salida);
fputs("EXP\n",salida);
}
void GeneraCodigo::sin(char *tipo)
{
cout<<tipo<<"SIN"<<endl;
fputs(tipo,salida);
fputs("SIN\n",salida);
}
void GeneraCodigo::tan(char *tipo)
{
cout<<tipo<<"TAN"<<endl;
fputs(tipo,salida);
fputs("TAN\n",salida);
}
#endif
Posteriormente, guarde el archivo con el nombre “genera.h”.
Luego proceda a compilar el proyecto.
Análisis de resultados
Proceda a integrar el analizador sintáctico y analizador
semántico al generador de código presentado anteriormente
para terminar la parte de traducción correspondiente al
compilador de MUSIM/3 desarrollado durante varias de las
prácticas de laboratorio.
Aun nos resta añadir al proyecto la interfaz principal del
compilador. A continuación en el archivo “ppal.cpp” de su
proyecto escriba el siguiente código, el cual sustituirá el
contenido anterior; recuerde que al haber adaptado e
integrado tanto el analizador semántico como el generador de
código con el analizador sintáctico, su parámetros de
instanciación han cambiado y ahora incluyen el archivo de
salida del resultado de la compilación, es decir el código en
lenguaje objeto.
ppal.cpp
/*
Compiladores. Guía 9 9
Compilador de MUSIM/3
*/
#include <cstdlib>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include "sintacti.h"
using namespace std;
int main (int argc, char *argv[])
{
int traza;
char fuente[40]={'\0'};
char objeto[40]={'\0'};
char d;
bool correcto=false;
do{
cout<<"Compilador MUSIM/3-EMSAMPOCO/0 Versión 3.0"<<endl;
cout<<" -Fich_fuente (MUSIM/3):"<<endl;
fflush(stdin);
gets(fuente);
cout<<" -Fich_objeto:"<<endl;
fflush(stdin);
gets(objeto);
if((fuente!='\0'))
{
traza=1;
correcto=true;
}
else {
cout<<"Datos erroneos, Desea salir del programa?s/n:
";
cin>>d;
if(d=='s')
break;
}
}while(!correcto);
if (!correcto)
{
cout<<"Saliendo de la aplicacion..."<<endl;
}
else
{
Sintactico sintactico(fuente,objeto,traza);
}
system("pause");
10 Compiladores. Guía 9
return 0;
}
Ahora coloque el siguiente archivo de texto en la misma
carpeta para compilarlo. Corresponde a un pequeño programa en
MUSIM/3.
prueba.txt
M{
I a;
I b;
F c;
F d;
R a;
R b;
c=a+b;
d=a-b;
W c;
W d;
}.
Pruebe su compilador sobre el archivo indicado.
Investigación complementaria
Realice un cuadro resumen de las principales instrucciones de
lenguaje ensamblador 8086, que incluya su descripción, forma
de uso y un ejemplo por cada uno de ellos. Mínimo 15
instrucciones.
Bibliografía

http://en.wikipedia.org/wiki/Code_generation_%28compiler
%29

Cuadernos didácticos. Conceptos básicos de procesadores
de
lenguaje.
Juan
Manuel
Cueva
Lovelle.
Oviedo,
Diciembre 1998.
Compiladores. Guía 9 11
9
1
Hoja de cotejo:
Guía 9: Generación de código
Docente:
Tema: Presentación del programa
Máquina No:
Máquina No:
Alumno:
Máquina No:
GL:
Alumno:
Docente:
GL:
Docente:
GL:
Fecha:
a
EVALUACION
%
1-4
5-7
8-10
CONOCIMIENTO
Del 20
al 30%
Conocimie
nto
deficient
e de los
fundament
os
teóricos
Conocimiento
y explicación
incompleta de
los
fundamentos
teóricos
Conocimiento
completo y
explicación
clara de los
fundamentos
teóricos
APLICACIÓN
DEL
CONOCIMIENTO
Del 40%
al 60%
No tiene
actitud
proactiva
.
Actitud
propositiva y
con
propuestas no
aplicables al
contenido de
la guía.
Tiene actitud
proactiva y sus
propuestas son
concretas.
ACTITUD
Del 15%
al 30%
TOTAL
100%
Nota
Descargar