Está en la página 1de 51

Memoria de la prctica de Compiladores

Entrega final del Compilador para Java


Grupo 24: Ramn Recuero Moreno Cristian Moral Martos Ral San Narciso Holguera 50980321-Q 53397324-H 45686650-W m050128 m050108 k030192

2008/2009

Pgina 1 de 130

Compilador de Java 08/09 Entrega final

2 Analizador Lxico
2.1 Tokens
Para poder definir la gramtica de nuestro analizador lxico, primero debemos definir cules van a ser los tokens que van a ser reconocidos por esta gramtica. Estos tokens sern todos aquellos que son obligatorios para nuestro grupo y tambin otros que hemos decidido escoger como optativos, de forma que al final nuestro compilador sea ms completo. Cada vez que el analizador lxico lea un token, devolver una tupla con el cdigo que identifica el tipo de token y el identificador para el token especfico, dentro de ese tipo de tokens, es decir: (Cdigo_Tipo_deToken, Identificador_Token). Para el caso del operador de asignacin y el operador de acceso a miembros de una clase, tan solo ser necesario el primer elemento de la tupla: (Cdigo_Tipo_deToken). Tipo token Identificador Operadores aritmticos Lexemas Formato token

Operadores lgicos

Operadores relacionales

Enteros Operador asignacin Operadores condicionales

{letra $ _} (Cod_Identificador, lexema) = (1, lexema) caracter* +, -, *, /, ++ (Cod_Op_aritmtico, Identificador_Op)=(2,Id_Aritmetico) id_Aritmetico (+)=0 id_Aritmetico (-)=1 id_Aritmetico (*)=2 id_Aritmetico (/)=3 id_Aritmetico (++)=4 &&, ||, ! (Cod_Op_lgico,cdigo)=(3,Id_Logico) Id_Logico(&&)=0 Id_Logico(||)=1 Id_Logico(!)=2 ==, !=, <, > (Cod_Op_relacional,cdigo)=(4,Id_Relacional) Id_Relacional(==)=0 Id_Logico(!=)=1 Id_Logico(<)=2 Id_Logico(>)=3 {d}* (Cod_Entero,Valor) = (5,valor) de = (Cod_Op_asignacion) = (6) ? : (Cod_Operador condicional,Id_Condicional)=(7,Id_Condicional) Id_Condicional(?)=0 Id_Condicional(:)=1 (Cod_Pal_Reservada, Id_Pal_Res) = (8, Id_Pal_Res) Pgina 5 de 130

Palabras reservadas

dowhile

Compilador de Java 08/09 Entrega final Operador de . acceso a miembros de una clase Cadenas {caracter}* Separadores ( ) , ; { } (Cod_Operador_acceso) = (9)

(Cod_Cadena,cadena) =(10,cadena) (Cod_Separador, Id_Separador)=(11,Id_Separador) Id_Separador(()=(0) Id_Separador())=(1) Id_Separador(,)=(2) Id_Separador(;)=(3) Id_Separador({)=(4) Id_Separador(})=(5)

2.2 Palabras Reservadas


Estas son las palabras propias del lenguaje Java que no podrn ser usadas como identificadores. Debemos de tener en cuenta todas las palabras reservadas que podrn ser utilizadas en nuestro compilador. Cada palabra reservada tendr asociado un nmero para poder diferenciarlas fcilmente, de forma que cuando el analizador lxico lea una palabra reservada, tan solo tendr que devolver este identificador junto con el propio de las palabras reservadas tal y como se ha indicado con anterioridad:

(Cod_Pal_Reservada, Id_Pal_Res) = (8, Id_Pal_Res) Id_Pal_Res 1 2 3 4 5 6 7 8 9 10 Token class public private void int char String boolean null main

Pgina 6 de 130

Compilador de Java 08/09 Entrega final 11 12 13 14 15 16 17 18 19 return true false do while this new print read

2.3 Gramtica
Esta gramtica ser la propia del analizador lxico, de forma que todas las palabras que reconozca sean tokens aceptados por nuestro analizador lxico. La gramtica viene definida de la siguiente forma: Smbolos no terminales = (S, A, B, C, D, E, F, G, H, I, J, K, N) Smbolos terminales = (letra letra2 letra3 letra4 letra5 letra6 digito + - * / & | ! = . , < > ? : ; ( ) { } del0 del1 del3 del4 del5 del6 CR ) GramticaALexico = { (S, A, B, C, D, E, F, G, H, I, J, K, N), (letra letra2 letra3 letra4 letra5 letra6 digito + - * / & | ! = . , < > ? : ; ( ) { } del0 del1 del3 del4 del5 del6 CR ), S, Producciones }

De esta manera, las producciones obtenidas son: S letraA | digitoN | +B | - | * | /H | &C | |D | !E | =F | . | , | G | O | < | > | ? | : | ; | ( | ) | { | } | del0S A letraA | digitoA | del2 B + | del1 C& D| E del3 | = F del5 | = Pgina 7 de 130

Compilador de Java 08/09 Entrega final

2.4 Autmata

Pgina 9 de 130

Compilador de Java 08/09 Entrega final

2.5 Acciones semnticas


Para el correcto funcionamiento del analizador lxico, le hemos aadido acciones semnticas que permitan generar los tokens deseados o detectar los errores.

2.5.1 Leer LEER


Esta accin semntica tiene como objetivo obtener el carcter que est en la entrada, y avanzar en dicha entrada para preparar el tratamiento del siguiente carcter. Algoritmo car := entrada[pos_Actual]; pos_actual++;

2.5.2 Concatenar CONC


Esta accin semntica tiene como objetivo concatenar los sucesivos caracteres ledos por el analizador lxico para formar el lexema completo. Algoritmo lexema := lexema + car;

2.5.3 Crear nmero NUM


Esta accin semntica tiene como objetivo ir formado un nmero a medida que se van leyendo los dgitos que lo forman. Algoritmo num := num*10+car;

2.5.4 Buscar lexema BUSCA


Esta accin semntica tiene como objetivo buscar el lexema ledo en la Tabla de Smbolos, para determinar si ya existe porque es una palabra reservada o es un lexema que ya se haba introducido anteriormente, o si por lo contrario no existe y por tanto hay que introducirlo.. Esta accin semntica se realiza llamando a las correspondientes existe_entrada de la tabla de smbolos y buscar de la tabla de palabras reservadas. Pgina 10 de 130

Compilador de Java 08/09 Entrega final

2.5.5 Aadir lexema AADE


Esta accin semntica tiene como objetivo aadir el lexema ledo en la Tabla de Smbolos. Algoritmo if ( not existe_entrada(Tabla_Pal_Res, lexema)) If (not existe_entrada(Tabla_Simbolos, lexema)) crear_entrada(Tabla_Simbolos, lexema);

2.5.6 Generar Token GEN_TOKEN


Esta accin semntica tiene como objetivo generar el token encontrado para envirselo al analizador semntico. La accin deber indicar el token que est enviando acorde con el formato establecido en la tabla de tokens.

2.5.7 Generar Error GEN_ERROR


Esta accin semntica tiene como objetivo informar al nivel semntico de que se ha producido un error durante el anlisis lxico. Debe informar del tipo de error segn lo establecido en la tabla de errores. Indicamos que el Analizador Semntico ser el encargado de indicar el lugar donde se ha producido el error.

2.5.8 Lista de acciones semnticas a realizar


Seguidamente especificamos qu acciones semnticas se producen y en qu transiciones o estados lo hacen: LEER: Se produce en todas las transiciones, excepto en las que se lee un delimitador. Por tanto las transiciones en las que no tendra lugar son: 1-34, 12-33, 8-25, 2-25, 5-30 y 6-31. CONC: Se produce en las transiciones: 0-1 y 1-1. NUM: Se produce en las transiciones: 0-12 y 12-12. GEN_TOKEN: Se produce en todos los estados finales del autmata (excepto en el de los identificadores, el 34, donde se ejecuta un pequeo programa). Por tanto es ejecutado en los estados: 33, 25, 30, 27, 31, 28, 29, 26 Y 32.

Pgina 11 de 130

Compilador de Java 08/09 Entrega final GEN_ERROR: Se produce siempre que el autmata intente hacer una transicin que no existe, en cuyo caso se puede informar del tipo de fallo en funcin del estado en el que se encuentre el autmata, y del carcter recibido que ha provocado el fallo.

En algunos casos, lo que se ejecuta es un pequeo programa en el que, en funcin del caso, se ejecuta una accin semntica u otra. Es el caso por ejemplo del estado 34, en el que se ejecuta:

pos := BUSCA (lexema) if (pos = 0) pos := AADE(lexema) if (es_palabra_reservada(lexema)) GEN_TOKEN(Pal_Res, pos) else GEN_TOKEN(id_token, pos)

2.6 Implementacin
Indicamos que la implementacin del Analizador Lxico la hemos realizado con el lenguaje de programacin Python. Aunque hemos tenido que aprender este lenguaje en poco tiempo, lo hemos escogido por los numerosos consejos recibidos acerca de su facilidad de uso y tambin porque segn tenemos entendido Python nos pondr las cosas bastante fciles al implementar el Analizador Sintctico, y dado que no podemos usar ninguna herramienta como Yacc, debido a que nuestro Analizador Sintctico ha de ser Descendiente con Tablas, toda ayuda en este sentido ser buena.

Pgina 12 de 130

Compilador de Java 08/09 Entrega final

4 Analizador Sintctico
4.1 Gramtica
El primer paso para realizar la parte del Traductor Dirigido por Sintaxis correspondiente al Analizador sintctico y al Analizador semntico es realizar la gramtica de contexto libre que acepte las cadenas que debe reconocer el compilador. Los elementos de dicha gramtica, tanto terminales como no terminales, sern los proporcionados por el Analizador Lxico, realizado en la entrega anterior. As pues, la gramtica que hemos obtenido es la siguiente:

S class id { Cuerpo_Clase } S S class id { Cuerpo_Clase } S | Prioridad public | private | Tipo_Id int | boolean | String | char | void Valor_Id entero | cadena | carcter | true | false Cuerpo_Clase Prioridad Tipo_Id id A| id Constructor | A ( Param ) { Cuerpo_Funcion } Cuerpo_Clase | Asignacion_Atributo; Cuerpo_Clase Asignacion_Atributo = Valor_id| Constructor (Param) { Cuerpo_Funcion } Cuerpo_Clase Asignacion_Objeto =new id (Valor_Param)| Param Tipo_Id id Param_2 | Param_2 ,Param | Valor_Param id Valor_Param_2 | Valor_Id Valor_Param_2 | Valor_Param_2 , Valor_Param | Cuerpo_Funcion Sent ; Cuerpo_Funcion | Control Cuerpo_Funcion | return F; | Sent Tipo_Id id Asignacion | Desc_Gen Sent2 | print (Desc4) | read(id)

Pgina 14 de 130

Compilador de Java 08/09 Entrega final Sent2 ++|Asignacion | id Asignacion_Objeto | .id Asignacion | ( Valor_Param ) Desc Desc_Gen Desc2 | ! Desc_Gen Desc2 .id Desc3| (Valor_Param) | Desc3 (Valor_Param) | ++ | Desc4 id | cadena | entero | Desc_Gen id | this.id Control do { Cuerpo_Funcion } while (Asignacion_2); Asignacion = Asignacion_2| Asignacion_2 (Asignacion_2) D Asignacion_2 | Valor_id D Asignacion_2 | Desc D Asignacion_2 Asignacion_2 ? Asignacion_2 : Asignacion_2 | D Op Asignacion_2 | Op + | - | / | * | && | || | != | == | > | < F Asignacion_2|

4.2 Tabla de accin


Puesto que nuestro analizador sintctico es descendente por tablas, debemos calcular la tabla que indique las transiciones que puedan producirse al tener un no terminal dado en la pila y un terminal en la cinta de entrada. Para poder realizar dicha tabla, primero debemos calcular los FIRST y FOLLOW de cada uno de los no terminales de la gramtica.

4.2.1 FIRST
First (S) = {class} First (S) = {class, } First (Prioridad) = {public, private, } First (Tipo_Id) = {int, boolean, String, char, void} Pgina 15 de 130

Compilador de Java 08/09 Entrega final First (Desc4) = {id, cadena, entero} First (Desc_Gen) = {id, this} First (Control) = {do} First (Asignacion) = { =, } First (Asignacion_2 ) = { (, First(Valor_Id), First(Desc)} = { (,entero , cadena, carcter, true, false, id, this, !} First (Asignacion_2) = { ? , } First (D) = {First(Op), } = { +, -, / , * , && , || , ==, != , > , <, } First (Op) = { +, -, / , * , && , || , ==, != , > , <} First (F) = {First(Asignacion_2 , } = { (, entero, cadena, carcter, true, false, id, this, ! , }

4.2.2 FOLLOW
Follow (S) = {$} Follow (S) = {Follow(S)} = {$} Follow (Prioridad) = {First(Tipo_Id)} = {int, boolean, String, char, void} Follow (Tipo_Id) = {id} Follow (Valor_Id) = {Follow(Asignacion_Atribto), First(Valor_Param_2), Follow(Valor_Param_2), First(D), Follow(D)} = {; , , , ), +, -, / , * , && , || , ==, != , > , <, ?, , : } Follow (Cuerpo_Clase) = { }, Follow(A), Follow(Constructor)} ={} }

Pgina 17 de 130

Compilador de Java 08/09 Entrega final Follow (Desc4) = { ) } Follow (Desc_Gen) = {First(Sent2), First(Desc2), Follow(Desc2), Follow(Desc)} = { ++, =, , id, ., ( , +, -, / , * , && , || , ==, != , > , <, ?, ) , ; , : } Follow (Control) = {First(Cuerpo_Funcion), Follow(Cuerpo_Funcion) } = { int, boolean, String, char, void, id, this, print, read, do, return, } } Follow (Asignacion) = { Follow(Sent),Follow(Sent2)} ={;} Follow (Asignacion_2 ) = { ) , Follow(Asignacion), :, Follow(D), Follow(F)} = { ) , ; , :, ?} Follow (Asignacion_2) = { Follow(Asignacion_2) } = { ) , ; , :, ?} Follow(D) = {First(Asignacion_2), Follow(Asignacion_2)} = {?, ) , ; , : } Follow (Op) = {First(Asignacion_2 ) } = { (, entero , cadena, carcter, true, false, id, this, !} Follow (F ) = { ;}

4.2.3 Acciones
Una vez obtenido los FIRST y FOLLOW, podemos proceder a calcular la tabla de accin, que mas adelante nos permitir saber con qu terminales debe transitar cada uno de los no terminales y con qu producciones lo hace.

Esto es lo que se reflejar directamente en la implementacin, de ah su importancia.

Pgina 19 de 130

Compilador de Java 08/09 Entrega final

4.3 Implementacin
La implementacin del Analizador Sintctico ha sido realizada con el lenguaje de programacin Python. Aunque hemos tenido que aprender este lenguaje en poco tiempo, lo hemos escogido por los numerosos consejos recibidos acerca de su facilidad de uso y dado que no podemos usar ninguna herramienta como Yacc, ya que nuestro Analizador Sintctico ha de ser Descendiente con Tablas, toda ayuda en este sentido ser buena.

5 Analizador Semntico
El siguiente paso a realizar es incluir las acciones semnticas en la gramtica de contexto libre que realiza el anlisis sintctico. Para ello vamos a utilizar un Esquema de Traduccin (EDT). Para mejorar la comprensin de la gramtica ampliada con las acciones semnticas, en vez de incluir directamente el cdigo de dichas acciones en la gramtica, vamos a introducir ndices, que posteriormente indicarn que realiza dicha accin semntica.

S class id [1] { [33] Cuerpo_Clase } S [0] S class id [1] { [33] Cuerpo_Clase } [7] S [0] S Prioridad public [Prioridad.prioridad := public] Prioridad private [Prioridad.prioridad := private] Prioridad Tipo_Id int [Tipo_Id.tipo := int; despl := 2] Tipo_Id boolean [Tipo_Id.tipo := boolean; despl := 1] Tipo_Id String [Tipo_Id.tipo := string; despl := 2] Tipo_Id char [Tipo_Id.tipo := char; despl := 1] Tipo_Id void [Tipo_Id.tipo := void; despl := 0]

Pgina 28 de 130

Compilador de Java 08/09 Entrega final Valor_Id entero [Valor_Id.tipo := int] Valor_Id cadena [Valor_Id.tipo := string] Valor_Id carcter [Valor_Id.tipo := char] Valor_Id true [Valor_Id.tipo := boolean] Valor_Id false [Valor_Id.tipo := boolean] Cuerpo_Clase Prioridad Tipo_Id [34] id [2] A [10] Cuerpo_Clase id [57] Constructor [9] Cuerpo_Clase A ( Param [3]) { [33] Cuerpo_Funcion } [6] Cuerpo_Clase [11] A Asignacion_Atributo; Cuerpo_Clase [12] Asignacion_Atributo = Valor_id [4] Asignacion_Atributo Constructor ( [35] Param [3] ) { [33] Cuerpo_Funcion } [6] Cuerpo_Clase [11] Asignacion_Objeto =new id [62] (Valor_Param) [56] [64] Asignacion_Objeto Param Tipo_Id [34] id [5] Param_2 [13] Param Param_2 , Param [14] Param_2 Valor_Param id [50] Valor_Param_2 [15] Valor_Param Valor_Id [51] Valor_Param_2 [15] Valor_Param Valor_Param_2 , Valor_Param [16] Valor_Param_2 Cuerpo_Funcion Sent ; [8] Cuerpo_Funcion [17] Cuerpo_Funcion Control Cuerpo_Funcion [18] Pgina 29 de 130

Compilador de Java 08/09 Entrega final Cuerpo_Funcion return F; [19] Cuerpo_Funcion Sent Tipo_Id [34] id [22] Asignacion [54] Sent Desc_Gen [58] Sent2 [48] Sent print (Desc4) [20] Sent read (id [61]) [20] Sent2 ++ [7] Sent2 Asignacion [26] Sent2 id [23] Asignacion_Objeto [59] Sent2 . [66] id [67] Asignacion [26] Sent2 ( Valor_Param ) [29] Desc Desc_Gen Desc2 [27] Desc ! Desc_Gen [28] Desc2 . [60] id [31] Desc3 [30] Desc2 (Valor_Param [9]) [29] Desc2 Desc3 (Valor_Param) [49] Desc3 ++ Desc3 Desc4 id [63] Desc4 cadena Desc4 entero Desc4 Desc_Gen id [23] Desc_Gen this.id [24]

Pgina 30 de 130

Compilador de Java 08/09 Entrega final Control do { [33] Cuerpo_Funcion } while (Asignacion_2 [47] ); [41] Asignacion = [53] Asignacion_2 [32] Asignacion Asignacion_2 (Asignacion_2 [39] ) D [44] Asignacion_2 [45] Asignacion_2 Valor_id [37] D [44] Asignacion_2 [45] Asignacion_2 Desc [36] D [44] Asignacion_2 [45] Asignacion_2 ? Asignacion_2 : Asignacion_2 [42] Asignacion_2 D Op [38] Asignacion_2 [43] D Op + Op Op / Op * Op && Op || Op != Op == Op > Op < F Asignacion_2 [46] F

A continuacin explicamos, en lenguaje natural, qu realiza cada una de las acciones semnticas citadas segn su ndice en la gramtica anterior.

Pgina 31 de 130

Compilador de Java 08/09 Entrega final


43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 "Se esperaba el operador de incremento ++" "Se esperaba el operador resta -" "Se esperaba el operador de divisin /" "Se esperaba el operador lgico &&" "Se esperaba el operador lgico ||" "Se esperaba el operador relacional <" "Se esperaba el operador relacional >" "Se esperaba el operador de multiplicacin *" "Se esperaba el operador relacional ==" "Se esperaba el operador relacional !=" "Error de tipos en la asignacin del atributo" "El tipo de la variable devuelta es diferente del declarado" "El atributo no pertenece a la clase" "Los tipos en la asignacin han de ser iguales" "El nombre del constructor no coincide con el nombre de la clase" "La operacin '++' solo puede usarse con un entero" "se esperaba la palabra reservada 'new'" "Esperando identificador" "El nombre de la clase ya existe y no puede usarse" "No es un operador valido para los tipos elegidos" "Los tipos en la asignacin no concuerdan" "El tipo elegido no es vlido" "Los tipos en la sentencia no son correctos" "La sentencia do-while requiere una condicin booleana" "Los parmetros de la funcin tienen un tipo incorrecto" "El nmero de parmetros es incorrecto" El identificador no est definido Esperando identificador Declaracin incorrecta Atributo y/o funcin no visible dentro de la clase Se esperaba un id de tipo String o Int La construccin del objeto es incorrecta El main no tiene retorno. No se pueden declarar objetos como atributos de clase.

6.1 Implementacin
La implementacin del Analizador Semntico ha sido realizada, al igual que el Analizador Sintctico, con el lenguaje de programacin Python, debido a las facilidades mencionadas anteriormente.

Pgina 39 de 130

Compilador de Java 08/09 Entrega final

7 Generador de Cdigo Intermedio


7.1 Cdigo de 3 direcciones
Para la generacin del Cdigo Intermedio, hemos utilizado la notacin de Cdigo de 3 direcciones. Dentro de dicha notacin, hemos utilizado cuartetos.

Dichos cuartetos son los que nos permiten comunicarnos con el Generador de Cdigo Objeto, indicndole todos los datos necesarios para que genere las instrucciones en cdigo ensamblador correspondientes.

Seguidamente mostramos en qu puntos de la gramtica hemos creado y enviado cuartetos al Generador de Cdigo Intermedio para que genere su cdigo objeto.

Cabe resaltar que, como ya hemos indicado anteriormente, algunas de las funcionalidades optativas que se han implementado en los mdulos anteriores, no van a ser tenidas en cuenta partir de ahora. En la siguiente gramtica, dichas producciones se indicarn ponindolas en color azul.

S class id { Cuerpo_Clase } S[0] S class id { Cuerpo_Clase } S S Prioridad public Prioridad private Prioridad Tipo_Id int Tipo_Id boolean Tipo_Id String Tipo_Id char Pgina 40 de 130

Compilador de Java 08/09 Entrega final Tipo_Id void Valor_Id entero Valor_Id cadena Valor_Id carcter Valor_Id true Valor_Id false Cuerpo_Clase Prioridad Tipo_Id id A Cuerpo_Clase id Constructor Cuerpo_Clase A ( [1] Param ) { Cuerpo_Funcion } Cuerpo_Clase A Asignacion_Atributo; Cuerpo_Clase Asignacion_Atributo = Valor_id [2] Asignacion_Atributo [2] Constructor ( [1] Param ) { Cuerpo_Funcion } Cuerpo_Clase Asignacion_Objeto =new id (Valor_Param) Asignacion_Objeto Param Tipo_Id id Param_2 Param Param_2 , Param Param_2 Valor_Param id [10] Valor_Param_2 Valor_Param Valor_Id [10] Valor_Param_2 Valor_Param Valor_Param_2 , Valor_Param Valor_Param_2 Cuerpo_Funcion Sent ; Cuerpo_Funcion Pgina 41 de 130

Compilador de Java 08/09 Entrega final Cuerpo_Funcion Control Cuerpo_Funcion Cuerpo_Funcion return F [4] ; Cuerpo_Funcion Sent Tipo_Id id Asignacion [12] Sent Desc_Gen Sent2 Sent print (Desc4 [5] ) Sent read (id [6] ) Sent2 ++ [7] Sent2 Asignacion [12] Sent2 id Asignacion_Objeto Sent2 . id Asignacion Desc Desc_Gen Desc2 Desc ! Desc_Gen Desc2 . id Desc3 Desc2 (Valor_Param [9] ) Desc2 Desc3 (Valor_Param [11] ) Desc3 ++ [7] Desc3 Desc4 id Desc4 cadena Desc4 entero Desc4 Desc_Gen id Desc_Gen this.id

Pgina 42 de 130

Compilador de Java 08/09 Entrega final Control do [19] { Cuerpo_Funcion } while (Asignacion_2 ) [20]; Asignacion = Asignacion_2 Asignacion Asignacion_2 (Asignacion_2) D Asignacion_2 Asignacion_2 Valor_id D [13] Asignacion_2 Asignacion_2 Desc D [13] Asignacion_2 Asignacion_2 [16] ? [14] Asignacion_2 [18] : [15] Asignacion_2 [17] Asignacion_2 D Op Asignacion_2 D Op + Op Op / Op * Op && Op || Op != Op == Op > Op < F Asignacion_2 F

A continuacin explicamos, en lenguaje natural, qu indica cada uno de los cuartetos citados segn su ndice en la gramtica anterior.

Pgina 43 de 130

Compilador de Java 08/09 Entrega final 13 Cuarteto op Cuarteto de operacin (+). El operador, los operandos y el lugar en el que se tiene que almacenar el resultado. Cuarteto if_begin Cuarteto empleado para comunicar al GCO que ha de declarar una nueva etiqueta para tener localizado el inicio del flujo del operador condicional. Cuarteto if_else Comunica al GCO que cree una etiqueta para localizar el flujo de un else (en el operador condicional). Cuarteto salto_if Enva al GCO la informacin necesaria para que realice un salto a la etiqueta if_begin o if_else dependiendo del resultado una vez evaluada la condicin inicial. Cuarteto fin_if Cuarteto para indicar al GCO que declare una etiqueta en el lugar en el que se acaba el cdigo del condicional. Cuarteto salto_fin_if Independientemente de cul haya sido el resultado del operador condicional, salta al final del mismo. Cuarteto dow Cuarteto para indicar al GCO que declare una etiqueta necesaria para marcar el inicio del cdigo de la sentencia dowhile. Cuarteto dow-cond Enva que es necesario evaluar el resultado de la condicin que ha sido guardado en una variable temporal. Segn este resultado, el GCO tendr que realizar un salto condicional o seguir la ejecucin terminando as la sentencia do-while.

14

15

16

17

18

19

20

7.2 Implementacin
La implementacin del Generador de Cdigo Intermedio ha sido realizada, al igual que los mdulos anteriores, con el lenguaje de programacin Python, debido a las facilidades mencionadas anteriormente.

Pgina 45 de 130

Compilador de Java 08/09 Entrega final

8 Generador de Cdigo Objeto


8.1 Cdigo Ensamblador
Este mdulo ser el ltimo en intervenir en nuestro compilador. Su cometido es traducir la las instrucciones recibidas del Generador de Cdigo Intermedio, bajo la notacin de cdigo de 3 direcciones implementado con cuartetos, a instrucciones del Lenguaje Ensamblador, que son la que el ensamblador entiende para generar las instrucciones de bajo nivel, que son las nicas entendibles por una ordenador. Dichas instrucciones son atmicas y realizan operaciones simples. En efecto, podemos decir que en la mayora de los casos, sea cual sea la operacin, hemos utilizado slo operacin de movimiento de datos de un sitio a otro (MOVE) y operaciones bsicas aritmticas (ADD, SUB, INC). Tambin hemos utilizado las instrucciones CALL y RET para las llamadas y retornos de funciones. Gracias a qu disponemos de un ensamblador simblico, no debemos preocuparnos de la gestin de los registros, ya que lo hace en propio ensamblador. Adems, hemos utilizado etiquetas para apuntar al inicio de las instrucciones de cada una de las funciones a las que se llame durante la ejecucin del programa (slo hay una etiqueta por funcin, aunque se llame a sta varias veces, ya que el cdigo es el mismo, y el contenido, que es variable segn la llamada, se guarda en el Registro de Activacin de cada funcin). Seguidamente mostraremos algunos ejemplos de las instrucciones que hemos usado para traducir las instrucciones de cdigo de 3 direcciones:

a\ Almacenamiento de la Direccin de Retorno en el Registro de Activacin de una funcin que acaba de ser llamada: MOVE .SP, .IY MOVE .SP, #%d[.IY] ; siendo %d el tamao del Registro de Activacin de la funcin llamante En este caso movemos la direccin apuntada por SP a la direccin de memoria apuntada por SP ms el tamao del registro, es decir almacenamos el contenido de SP en la primera posicin del siguiente registro de activacin.

Pgina 46 de 130

Compilador de Java 08/09 Entrega final b\ Llamada a una funcin, que tiene una etiqueta INICIO apuntando a su primera instruccin: CALL /INICIO En este caso realizamos un CALL a la funcin INICIO, es decir se desplaza PC a la direccin almacenada en la posicin de memoria indicada por la etiqueta INICIO.

c\ Almacenamiento de un parmetro en el Registro de Activacin de una funcin que acaba de ser llamada: MOVE #%desp, [.SP] ; siendo %desp el desplazamiento del parmetro dentro del Registro de Activacin

8.2 Implementacin
La implementacin del Generador de Cdigo Objeto se ha realizado con el Ensamblador Simblico ENS L-ENS2001, que es uno de los proporcionados en la asignatura. Las razones de nuestra eleccin han sido un poco aleatorias, aunque influy que el manual de uso de las instrucciones que implementa dicho ensamblador nos pareci muy completo.

Pgina 47 de 130

Compilador de Java 08/09 Entrega final

9 Entorno de ejecucin
9.1 Organizacin de memoria
La estrategia de asignacin de memoria que hemos usado es el de Pila, ya que nuestro compilador debe implementar recursividad y secuencias de llamada y retorno, y nuestro lenguaje no es concurrente. As pues, nuestros registros de activacin se almacenarn en una Pila de Registros de Activacin.

9.2 Registros de activacin


Con el objetivo de poder implementar llamadas a funciones y/o procedimientos, hemos implementado registros de activacin que almacenen todos los datos necesarios para dichas llamadas y sus ejecuciones.

Al haber un Registro de Activacin por cada funcin, las diferentes llamadas a cada una de ellas puede recibir parmetros con valores diferentes, sus variables pueden tomar valores diferentes y el valor devuelto tambin podr ser diferente ya que todos ellos se almacenan en los respectivos Registros de Activacin.

Pgina 48 de 130

Compilador de Java 08/09 Entrega final Seguidamente, ilustramos el modelo de registro de activacin que hemos utilizado.

2 bytes

DIRECCIN RETORNO

2 bytes

ENLACE DE ACCESO

M * mi bytes

PARMETROS

n bytes

VALOR DEVUELTO

P * pi bytes

VARIABLES LOCALES

Q * qi bytes

VARIABLES TEMPORALES

En primer lugar, almacenamos la Direccin de retorno que ocupa 2 bytes. Dicha direccin almacena la direccin de inicio del Registro de Activacin de procedimiento funcin superior (el llamante), que ser siempre el inmediatamente anterior, puesto que no implementamos llamadas concurrentes, y por tanto el Registro de Activacin anterior ser siempre el del llamante.

Pgina 49 de 130

Compilador de Java 08/09 Entrega final En segundo lugar, almacenamos el Enlace de acceso que ocupa 2 bytes. Dicho enlace almacena la direccin del Enlace de acceso de la funcin en la que se ha definido la funcin o procedimiento llamado, que no tiene por qu ser el llamante. Esto es necesario para conocer que variables estn en su mbito de visibilidad, y por tanto son visibles para l. En nuestro caso, al no tener procedimientos anidados, dicho enlace apuntar siempre al Enlace de acceso del Registro de Activacin inmediatamente anterior en la pila de Registros de Activacin. Seguidamente, se almacenan los valores recibidos de los Parmetros de la funcin o procedimiento. El tamao que se reserve depender del nmero de parmetros que reciba la funcin por cabecera (M) y del tamao que ocupe el tipo de cada uno de ellos (mi). Tras esto, el Registro de Activacin reserva n bytes para el Valor Devuelto por la funcin. Evidentemente, n depender del tipo del valor que devuelva la funcin: o 2 bytes: entero y cadena (ya que se almacena la direccin a memoria dinmica que almacena la cadena) o 1 byte: carcter y boolean o 0 bytes: void A continuacin, se almacenan las Variables Locales que se hayan definido en la funcin. El tamao que se reserve depender del nmero de variables locales que se hayan declarado en el mbito local de la funcin (P) y del tamao que ocupe el tipo de cada una de ellas (pi). Por ltimo, se almacenan las Variables Temporales que se necesiten para almacenar valores temporales, por ejemplo para valores constantes o resultados parciales de operaciones. El tamao que se reserve depender del nmero de variables temporales que se necesiten para realizar todas las operaciones que tenga la funcin (Q) y del tamao que ocupe el tipo de cada una de ellas (qi).

As pues, vemos que el tamao de los Registros de Activacin depender de las funciones a las que correspondan, y ms concretamente de los parmetros que reciba, de las variables locales que se declaren, del valor que devuelvan y de las operaciones que se realicen dentro de la funcin.

Pgina 50 de 130

Compilador de Java 08/09 Entrega final

10 Casos de prueba
10.1 Casos errneos

Para todos las pruebas erroneas mostraremos el cdigo, sealando los lugares en los que se cometen los fallos para que as sea facil identificarlos con la salida generada por el compilador que tambin se aade a continuacin de cada prueba. Dado que nuestro compilador se para al primer error encontrado, incluimos todas las salidas tras la correccin de las mismas, hasta llegar a corregir el cdigo por completo. Los casos correctos se mostrarn en el siguiente apartado de Casos correctos, estos sern los mismos solo que en en esta ocasin se mostrar el cdigo objeto generado en lugar de la salida del compilador.

10.1.1
10.1.1.1

VeinteIteraciones
Cdigo

Pgina 51 de 130

Compilador de Java 08/09 Entrega final

10.1.1.2

Error devuelto

Pgina 52 de 130

Compilador de Java 08/09 Entrega final

10.1.2
10.1.2.1

Cuadrado
Cdigo

Pgina 53 de 130

Compilador de Java 08/09 Entrega final

10.1.2.2

Error devuelto

10.1.3
10.1.3.1

DiasSemana
Cdigo

Pgina 54 de 130

Compilador de Java 08/09 Entrega final

10.1.3.2

Error devuelto

Pgina 55 de 130

Compilador de Java 08/09 Entrega final

10.1.4
10.1.4.1

Calendario
Cdigo

Pgina 56 de 130

Compilador de Java 08/09 Entrega final

10.1.4.2

Error devuelto

Pgina 57 de 130

Compilador de Java 08/09 Entrega final

10.1.5
10.1.5.1

Erik
Cdigo

Pgina 58 de 130

Compilador de Java 08/09 Entrega final

Pgina 59 de 130

Compilador de Java 08/09 Entrega final

Pgina 60 de 130

Compilador de Java 08/09 Entrega final

10.1.5.2

Error devuelto

Pgina 61 de 130

Compilador de Java 08/09 Entrega final

10.1.6
10.1.6.1

Objetos
Cdigo

Pgina 62 de 130

Compilador de Java 08/09 Entrega final

10.1.6.2

Error devuelto

Pgina 63 de 130

Compilador de Java 08/09 Entrega final

10.1.7
10.1.7.1

CopiaStrings
Cdigo

10.1.7.2

Error devuelto

Pgina 64 de 130

Compilador de Java 08/09 Entrega final

10.2

Casos correctos
VeinteIteraciones
Cdigo

10.2.1
10.2.1.1

Pgina 65 de 130

Compilador de Java 08/09 Entrega final

10.2.2
10.2.2.1

Cuadrado
Cdigo

Pgina 69 de 130

Compilador de Java 08/09 Entrega final

10.2.3
10.2.3.1

DiasSemana
Cdigo

10.2.3.2

Cdigo Objeto generado


ORG 0 MOVE #30000, .IX MOVE #30002, .SP CALL /MAIN NOP ADD #1,.SP MOVE .A,.SP MOVE #0,.A MOVE #1, .A MOVE .SP,.IY MOVE .A, #6[.IY] MOVE #0,.A ; ; ; ; ; ; ; ; ; ; ; ; Inicializamos el registro de activacion Inicializamos la pila Saltamos al main Sumamos 1 para evitar el PC Apilamos la dir. de retorno limpiamos el acumulador asignamos un valor a el acumulador Movemos SP a IY asignamos un valor a una variable limpiamos el acumulador

DiasSemana_imprimeSemana:

Pgina 76 de 130

Compilador de Java 08/09 Entrega final

10.2.4
10.2.4.1

Calendario
Cdigo

Pgina 83 de 130

Compilador de Java 08/09 Entrega final

10.2.4.2

Cdigo Objeto generado


ORG 0 MOVE #30000, .IX MOVE #30002, .SP MOVE .SP,.IY MOVE #15, #6[.IY] MOVE #0,.A CALL /MAIN NOP ADD #1,.SP MOVE .A,.SP MOVE #0,.A MOVE #1, .A MOVE .SP,.IY MOVE .A, #10[.IY] MOVE #0,.A MOVE .SP,.IY INC #6[.IY] NOP MOVE #0,.R1 MOVE .SP,.IY MOVE #10[.IY],.R0 CMP .R0,.R1 BZ $5 MOVE #0,.A BR $3 MOVE #1,.A CMP .A,#1 MOVE #0,.A BNZ /if_else0 NOP BR $100 DATA "Falla " MOVE #Calendario_imprimeDia_res,.IY MOVE #0,#7[.IY] BR /end_if0 NOP MOVE #1,.R1 MOVE .SP,.IY MOVE #10[.IY],.R0 CMP .R0,.R1 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Inicializamos el registro de activacion Inicializamos la pila Movemos SP a IY asignamos un valor a una atributo limpiamos el acumulador Saltamos al main Sumamos 1 para evitar el PC Apilamos la dir. de retorno limpiamos el acumulador asignamos un valor a el acumulador Movemos SP a IY asignamos un valor a una variable limpiamos el acumulador Movemos SP a IY asignamos un valor a una variable movemos Movemos SP a IY asignamos un valor a R0 comparacin al acumulador comparacin al acumulador Comparacin fallida Comparacin exitosa limpiamos el acumulador

Calendario_imprimeDia:

dow_0:

if_begin0: Calendario_imprimeDia_res:

Guardamos la cadena Guardamos dir2 Movemos un byte

if_else0:

movemos Movemos SP a IY asignamos un valor a R0 comparacin al acumulador

Pgina 84 de 130

Compilador de Java 08/09 Entrega final

10.2.5
10.2.5.1

Erik
Cdigo

Pgina 110 de 130

Compilador de Java 08/09 Entrega final

Pgina 111 de 130

Compilador de Java 08/09 Entrega final

10.2.5.2

Cdigo Objeto generado


; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Inicializamos el registro de activacion Inicializamos la pila Saltamos al main Sumamos 1 para evitar el PC Apilamos la dir. de retorno limpiamos el acumulador Guardamos la cadena Guardamos la cadena Guardamos la cadena Guardamos la cadena Guardamos la cadena Guardamos la cadena Guardamos la cadena escribimos una cadena Guardamos la cadena escribimos una cadena Leemos una cadena escribimos una cadena Guardamos la cadena escribimos una cadena Guardamos la cadena escribimos una cadena Guardamos la cadena escribimos una cadena escribimos una cadena Guardamos la cadena escribimos una cadena Guardamos la cadena escribimos una cadena Leemos una cadena escribimos una cadena Guardamos la cadena escribimos una cadena

Erik_historia:

Erik_historia_erik: Erik_historia_pais: Erik_historia_planeta: Erik_historia_sistema: Erik_historia_estrella: Erik_historia_galaxia: cadena_0:

cadena_1:

cadena_2:

cadena_3:

cadena_4:

cadena_5:

cadena_6:

cadena_7:

ORG 0 MOVE #30000, .IX MOVE #30002, .SP CALL /MAIN NOP ADD #1,.SP MOVE .A,.SP MOVE #0,.A BR $100 RES 100 BR $100 RES 100 BR $100 RES 100 BR $100 RES 100 BR $100 RES 100 BR $100 RES 100 BR $18 DATA "Cmo te llamas?" WRSTR /cadena_0 BR $2 DATA "\n" WRSTR /cadena_1 INSTR /Erik_historia_erik WRSTR /Erik_historia_erik BR $15 DATA " naci en ... " WRSTR /cadena_2 BR $2 DATA "\n" WRSTR /cadena_3 BR $23 DATA "En qu pas naci " WRSTR /cadena_4 WRSTR /Erik_historia_erik BR $1 DATA "?" WRSTR /cadena_5 BR $2 DATA "\n" WRSTR /cadena_6 INSTR /Erik_historia_pais WRSTR /Erik_historia_erik BR $10 DATA " nacio en " WRSTR /cadena_7

Pgina 112 de 130

Compilador de Java 08/09 Entrega final

10.2.6
10.2.6.1

Objetos
Cdigo

Pgina 117 de 130

Compilador de Java 08/09 Entrega final

10.2.7
10.2.7.1

CopiaStrings
Cdigo

10.2.7.2

Cdigo Objeto generado


ORG 0 MOVE #30000, .IX MOVE #30002, .SP BR $100 DATA "hola" MOVE #CopiaStrings_main_res,.IY MOVE #0,#6[.IY] BR $4 DATA "hola" MOVE #aux0,.IX MOVE #CopiaStrings_main_res,.IY MOVE #0[.IX],#0[.IY] MOVE #aux0,.IX MOVE #CopiaStrings_main_res,.IY MOVE #1[.IX],#1[.IY] MOVE #aux0,.IX MOVE #CopiaStrings_main_res,.IY MOVE #2[.IX],#2[.IY] MOVE #aux0,.IX MOVE #CopiaStrings_main_res,.IY ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Inicializamos el registro de activacion Inicializamos la pila Guardamos la cadena Guardamos dir2 Movemos un byte Guardamos la cadena Guardamos dir1 Guardamos dir2 Movemos un byte Guardamos dir1 Guardamos dir2 Movemos un byte Guardamos dir1 Guardamos dir2 Movemos un byte Guardamos dir1 Guardamos dir2

CopiaStrings_main_res:

aux0:

Pgina 122 de 130

También podría gustarte