Nombre del proyecto: Compilador Cr. Objetivo general del proyecto

Anuncio
Nombre del proyecto:
Compilador Cr.
Objetivo general del proyecto:
Desarrollar un compilador para analizar códigos escritos en lenguaje Cr (C reducido) y traduciros a código
equivalente en ensamblador para una máquina hipotética tipo RISC empleando en este proceso las herramientas
Lex, Yacc, GTK+ y Dev-Cpp.
Objetivos particulares y ponderación1:
− Implementar la interfaz gráfica de usuario
− Desarrollar la gramática de análisis
− Validar la semántica del código
− Generar el código ensamblador
[20%]
[30%]
[20%]
[30%]
Descripción de los objetivos particulares:
- Implementar la interfaz gráfica de usuario:
Se trata de una interfaz de desarrollo integrado que permita:
1. Edición con resaltado tipográfico2 de: palabras reservadas (int, void, if, else, switch, case, break, for,
while y do), operadores (+, -, ++, --, =, ==, >, <, >=, += y !=), símbolos (;, ,, (, ), [, ], {, } y :), constantes
literales de tipo entero y comentarios, mostrando en todo momento el número de línea y columna del
cursor de edición en una barra de estado.
2. Visualización de errores sintácticos y semánticos lo más descriptivo posible indicando el número de
línea donde se produce, la causa o causas del posible error y el último token involucrado.
3. Visualización del código objeto generado, solo en el caso de que el código fuente no contenga errores.
4. Funcionalidades comunes de Nuevo, Abrir, Guardar, Acerca de, y Salir, además de un botón para
compilar. Las funcionalidades de Abrir y Guardar deberán utilizar los cuadros de diálogo estándar
diseñados para tal fin.
- Desarrollar la gramática de análisis:
El código fuente es de tipo C reducido con las siguientes características:
1. La inclusión de librerías no es necesaria dado que no se tendrán sentencias de entrada/salida.
2. El código inicia con una sección de declaración de variables, las cuales solo pueden ser de tipo entero
positivo o negativo.
3. Las variables pueden estar inicializadas o no.
4. Es posible declarar variables simples o arreglos.
5. Se cuenta con una única función main de tipo void. En esta función no se permite la declaración de
variables.
6. Las únicas operaciones aritméticas válidas son la suma y la resta empleando para ello los operadores de
+, -, ++ y --.
7. Los operadores relacionales válidos son: ==, <, >, >=, <=, y !=.
8. Todas las sentencias de asignación y/o cálculo deben terminar con el símbolo de punto y coma, inclusive
las sentencias de declaración de variables.
9. Las sentencias de control (if, if-else, switch, for, while, do-while) siempre deben ir acompañadas de un
bloque de sentencias encerrado entre llaves, aún cuando se trate de una sola sentencia asociada a la
estructura de control.
10. Los anidamientos entre estructuras de control están permitidos sin restricciones.
11. Los comentarios pueden aparecer en cualquier parte del código y pueden ser de una línea (//) o de un
bloque de líneas (/**/).
1
La ponderación es tentativa.
Los colores mostrados en el texto son solo una sugerencia, sin embargo si se requiere que cada resaltado
tipográfico tenga un color distinto y diferente de negro.
2
El siguiente código ejemplifica la mayoría del conjunto de características antes mencionadas:
/*Ordenamiento burbuja*/
int n = 5, a[5] = {5, 8, 6, 2, 9}, aux;
int i, j;
void main( )
{
for(i = 2; i < n; i++){
for(j = 0; j < n-i; j++){
if( a[j] > a[j+1] ){
aux = a[j];
a[j] = a[j+1];
a[j+1] = aux;
}
}
}
}
Validar la semántica del código:
Las validaciones semánticas a realizar son las siguientes:
Los enteros (constantes literales) deben estar en el rango de -32768 a 32767 (Advertencia).
Todas las variables declaradas deben utilizarse en el código de la función principal (Advertencia).
A una variable de tipo arreglo no se le puede asignar un simple valor (Error).
Una variable de tipo arreglo no puede ser usada directamente en una operación de cálculo o
asignación, siempre deberá utilizarse indicando un elemento (Error).
Si el elemento de un arreglo es indicado mediante un valor literal, este no debe ser mayor al tamaño
del arreglo (Error).
Una variable de tipo arreglo no puede ser usada como índice de un arreglo directamente, solo a
través de uno de sus elementos (Error).
Verificar que en un ciclo for el incremento o decremento del contador sea coherente con la
condición de paro (Advertencia).
Verificar en los ciclos de tipo while y do-while que el valor de al menos una de las variables
involucradas en la condición cambien en el cuerpo del ciclo (Advertencia).
Generación de código ensamblador:
El código ensamblador a generar supone una máquina RISC (Acrónimo en inglés para Computador de Conjunto
Reducido de Instrucciones) de 16 bits en una arquitectura Harvard (memoria de datos y programa separados).
El conjunto de instrucciones disponibles es el siguiente:
Instrucción
LWI
LW
SWI
SW
ADD
ADDI
SUB
SUBI
BEQI
Ejemplo
LWI Rd, num16
LW Rd, D(Rt)
SWI Rd, D
SW Rd, D(Rt)
ADD Rd, Rt, Rs
ADDI Rd, Rt, num12
SUB Rd, Rt, Rs
SUBI Rd, Rt, num12
BEQI Rd, Rt, D
Significado
Rd = num16
Rd = Mem[Rt+D]
Mem[D] = Rd
Mem[Rt+D] = Rd
Rd = Rt + Rs
Rd = Rt + num12
Rd = Rt – Rs
Rd = Rt – num12
if(Rd == Rt) goto D
Instrucción
BNEI
BLTI
BGTI
CMP
BEQ
BNE
BLT
BGT
B
Ejemplo
BNEI Rd, Rt, D
BLTI Rd, Rt, D
BGTI Rd, Rt, D
CMP Rt, Rs
BEQ D
BNE D
BLT D
BGT D
BD
Significado
if(Rd != Rt) goto D
if(Rd < Rt) goto D
if(Rd > Rt) goto D
Rt – Rs
if(Rt == Rs) goto D
if(Rt != Rs) goto D
if(Rt < Rs) goto D
if(Rt > Rs) goto D
PC – D
Descargar