Tema: Generación de código intermedio

Anuncio
Compiladores. Guía 10
1
Facultad:
Ingeniería
Escuela:
Computación
Asignatura: Compiladores
Tema: Generación de código intermedio
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.
Material y Equipo
Guía de Laboratorio Nº 10.
Computadora con programa Dev C++
Introducción Teórica
Guía
3 guía se abordarán los conceptos pertenecientes al
En
esta
componente de generación de código, se implementara un
Guía 4
generador
de código en lenguaje C++ para el compilador del
lenguaje MUSIM.
fía
Generación de código.
La entrada para el generador de código consta de la
representación intermedia del programa fuente producida por
la etapa inicial junto con la información de la tabla de
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.
• Representaciones lineales:
Tercetos
Cuartetos
Máquinas a pila
• Representaciones arborescentes:
Árboles de análisis sintácticos
Grafos dirigidos a cíclicos
2
Compiladores. Guía 10
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 10 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
Guía
3 guía vamos a implementar el generador de código para
En
esta
nuestro mini proyecto del compilador MUSIM a ENSAMPOCO, para
Guía 4
ello
crearemos dos archivos en C++, uno de cabecera o
extensión “.h” y uno de desarrollo extensión “.cpp”.
fía
Primero debe buscar su proyecto de este compilador creado en
la guía 6 de analizador sintáctico. Abra el programa “Dev
C++” y abra el respectivo archivo de proyecto que tiene
creado previamente (poseerá una extensión de archivo “.dev”).
4
Compiladores. Guía 10
Posteriormente, añada al proyecto
digite el siguiente código:
un archivo fuente. Luego
genera.h
#ifndef GENERA_H
#define GENERA_H
#include <stdio.h>
#include <iostream.h>
#include <stdlib.h>
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 direccion);
void load();
void store();
void neg();
void add();
void mul();
void div();
void mod();
void input(char direccion);
void output(char direccion);
void end();
};
#endif
Al terminar deberá guardar el archivo con el nombre
“genera.h”. A continuación agregara al proyecto otro archivo
fuente. Dentro de este escribirá las definiciones de la clase
declarada en el archivo anterior. Digite el siguiente codigo:
Compiladores. Guía 10 5
genera.cpp
#include "genera.h"
GeneraCodigo::GeneraCodigo(char *unNombreFichero)
{
if ((salida=fopen(unNombreFichero,"w"))==NULL)
{
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);
fputc(constante,salida);
fputc('\n',salida);
}
void GeneraCodigo::pusha(char direccion)
{
cout<<"PUSHA "<<direccion<<endl;
fputs("PUSHA ",salida);
fputc(direccion,salida);
fputc('\n',salida);
}
void GeneraCodigo::load()
{
cout<<"LOAD"<<endl;
fputs("LOAD\n",salida);
}
void GeneraCodigo::store()
{
cout<<"STORE"<<endl;
fputs("STORE\n",salida);
}
el
6
Compiladores. Guía 10
void GeneraCodigo::neg()
{
cout<<"NEG"<<endl;
fputs("NEG\n",salida);
}
void GeneraCodigo::add()
{
cout<<"ADD"<<endl;
fputs("ADD\n",salida);
}
void GeneraCodigo::mul()
{
cout<<"MUL"<<endl;
fputs("MUL\n",salida);
}
void GeneraCodigo::div()
{
cout<<"DIV"<<endl;
fputs("DIV\n",salida);
}
void GeneraCodigo::mod()
{
cout<<"MOD"<<endl;
fputs("MOD\n",salida);
}
void GeneraCodigo::input(char direccion)
{
cout<<"INPUT "<<direccion<<endl;
fputs("INPUT ",salida);
fputc(direccion,salida);
fputc('\n',salida);
}
void GeneraCodigo::output(char direccion)
{
cout<<"OUTPUT "<<direccion<<endl;
fputs("OUTPUT ",salida);
fputc(direccion,salida);
fputc('\n',salida);
}
void GeneraCodigo::end()
{
cout<<"END"<<endl;
fputs("END\n",salida);
}
Posteriormente, guarde el archivo con el nombre “genera.cpp”.
Luego proceda a compilar el proyecto.
Compiladores. Guía 10 7
Análisis de resultados
Vamos a integrar el generador de código al analizador
sintáctico de la guía 6. Para ello dentro del analizador
sintáctico, cree un objeto de la clase de generación de
código y en los procedimientos que corresponda, llamar a las
operaciones del generador de código que genere el código
adecuado.
Ahora coloque el siguiente archivo de texto en la misma
carpeta para compilarlo. Corresponde a un pequeño programa en
MUSIM/0.
prueba.txt
M
{
R a;
R b;
c = a + b;
W c;
}
Pruebe su compilador sobre el archivo indicado.
Investigación complementaria
Investigue la generación de código ensamblador (asm) INTEL
con Dev C++.
Investigue las características y ventajas de los compiladores
de una y varias pasadas.
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.
8
Compiladores. Guía 10
10
1
Hoja de cotejo:
Guía 10: Generación de código
Docente:
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