You are on page 1of 35

Instituto Tecnolgico de Tepic

Lenguajes y Automatas II
Manual Tecnico: Lenguaje GOS.

Alumno: Numero de Control:


Rivera Zavala Gianny Eduardo. 12400316
Snchez Partida Hctor Omar. 12400322
Vera Enriquez Stevens Javier 12400333

Profesor: Ibarra Carlos Francisco.

Hora de clase: 11:00-12:00 pm.

Tepic, Nayarit a 28 de Junio de 2017.


Introduccin
En este manual encontraremos toda la informacin correspondiente al compilador
desarrollado en la materia de lenguajes y autmatas 1.
Contenido
FILOSFICA 2
CONCISIN NOTACIONAL 3
ORTOGONALIDAD 3
ABSTRACCIN 3
SEGURIDAD 4
EXPRESIVIDAD 4
EXTENSIBILIDAD 4
PORTABILIDAD 4
EFICIENCIA 5
Tabla de smbolos 5
Anlisis Lexico 6
Anlisis Sintactico 6
Gramticas 6
Reglas para las gramticas (P) 6
Smbolos terminales (T) 11
Smbolos no terminales (N) 11
Gramticas de atributos 12
Anlisis Semntico 12
Manejador de errores semnticos 13
Cdigo Intermedio 15
Cdigo de tres direcciones 16
Esquemas de generacin 17
Generacin de cdigo intermedio en GOS Compiler 18
Gramticas en Cdigo Intermedio: 18
BIBLIOGRAFA 33
FILOSFICA
Java est basado en C y C++, uno de los principales diseos de filosofa de estos lenguajes
es que el programador siempre est al cargo, el cual Java tambin adopta. Java le da al
programador el control total. Si t programas bien, tus programas lo reflejan. Si t no
programas muy bien, tus programas tambin lo reflejan. Dicho de otra manera, Java no es
un lenguaje con ruedas de entrenamiento. Es un lenguaje para programadores
profesionales.
Java tiene una propiedad en comn con C y C++: fue diseado, probado y mejorado por
programadores reales.
Es un lenguaje rodeado de las necesidades y experiencias de la gente quien lo ide. No
hay una mejor manera de producir uno de los mejores lenguajes profesionales de
programacin.

CONCISIN NOTACIONAL
El lenguaje debe ser entendible por parte del programador, ayudndolo a realizar el
diseo de sus programas. La sintaxis debe ser comprensible. Java contiene concisin
notacional porque es entendible, las palabras reservadas utilizadas son en ingls para cada
accin en espaol.
Si se requiere realizar un ciclo desde 1 a 10 se utiliza la estructura for o si se requiere
realizar una condicin si 1 es mayor que x, esa es la forma de aplicarlo en Java if(1>x)
lo que le permite al programador una sintaxis comprensible y fcil de hacer.

ORTOGONALIDAD
Ofrece la posibilidad de combinar diferentes caractersticas de muchas formas. La falta de
definicin de un lenguaje puede suponer la enumeracin de situaciones excepcionales o la
aparicin de incoherencias. Para los tipos primitivos se pueden comparar sus valores por
medio del operador: ==, pero para los objetos se debe usar el mtodo equals. Los tipos
primitivos se pasan por valor y los objetos por referencia.
ABSTRACCIN
El lenguaje debe permitir al programador la identificacin de patrones repetitivos y
automatizar tareas mecnicas, tediosas o susceptibles de cometer errores. Ejemplos de
tcnicas de abstraccin son los procedimientos y funciones, la genericidad, los lenguajes
de patrones de diseo, etc.
es posible hacer tareas repetitivas sin tener que hacer cada una de ellas, si se quiere
realizar en Java una suma de cuatro elementos, en lugar de hacer: int a=a+c+d+e es
posible realizar una funcin public int suma(a,b,c,d), dentro de ella se define la funcin y
solamente se requiere poner los valores.

SEGURIDAD
Lo ideal es que los programas incorrectos no pertenezcan al lenguaje y sean rechazados
por el compilador.
Se asegura que todos los programas hechos salgan con cierta calidad y no tengan errores,
Java, siempre marca cada error encontrado, garantizando de esta manera que la
aplicacin no contenga errores ya sean sintcticos o semnticos en la gramtica.

EXPRESIVIDAD
El programador debe poder expresar sus intenciones. En ocasiones, demasiada
expresividad puede implicar falta de seguridad.
Es la capacidad en que dicho lenguaje puede ayudar a expresar las cosas del mundo real
tal como es, en Java existen diferentes tipos de datos, desde enteros, flotantes, dobles,
imgenes, objetos, entre otros. Existen tambin estructuras, listas, pilas, colas, listas
doblemente enlazadas, etc. Variables locales, globales, funciones y procedimientos.

EXTENSIBILIDAD
Facilita la expresin, es posible crear nuevas estructuras que permitan realizar las
expresiones. En Java es posible crear objetos los cuales pueden ser una nueva estructura,
ejemplo el objeto alumno que contiene nombre, edad, sexo, etc. Es posible crear la
estructura para definirlo alumno a=new alumno (Jos, 20,H,...).
PORTABILIDAD
El lenguaje debe facilitar la creacin de programas que funcionen en el mayor nmero de
entornos computacionales. Este requisito es una garanta de supervivencia de los
programas escritos en el lenguaje y, por tanto, del propio lenguaje. Para conseguir la
portabilidad, es necesario limitar las caractersticas dependientes de una arquitectura
concreta.
Java es un lenguaje multiplataforma con el cual se pueden desarrollar
programas que se ejecuten sin problemas en sistemas operativos como
Windows, Linux, Mac, Unix, etc.
Java permite crear programas que se ejecuten en varios
dispositivos como computadoras, telfonos mviles, algunas consolas de
juegos y algunos electrodomsticos adems de en microcontroladores.

EFICIENCIA
El programador debe poder expresar algoritmos suficientemente eficientes o el lenguaje
debe incorporar tcnicas de optimizacin de los programas escritos en l.
Java posibilita la modularidad, por lo que es factible realizar rutinas individuales que sean
usadas por diversas aplicaciones, por ejemplo tenemos una rutina de impresin que
puede ser til para el procesador de palabras, como para la hoja de clculo.
La programacin en Java, posibilita el desarrollo de aplicaciones bajo el esquema de
Cliente Servidor, como de programas distribuidos, lo que lo hace capaz de conectar dos o
ms ordenadores, realizando tareas simultneamente, y de esta manera consigue
distribuir el trabajo a efectuar.

Tabla de smbolos
En Compidgeot se emplean dos tablas de smbolos, una esttica para los
smbolos que encuentra en el analizador lxico, y otra (dinmica)
utilizada para identificadores y funciones.
En cada registro de la tabla de smbolos se guarda la informacin del
token, tal como:
Lnea
Columna
Valor
Tipo
Lexema
Estos atributos estn designados para poder evaluar las funciones y de
esta manera encontrar los errores sintcticos o semntico. Antes de
llegar al punto de estos anlisis, se ejecuta el anlisis lxico, el cual
detecta todo aquel smbolo que no sea aceptado por el alfabeto del
lenguaje.

La implementacin de la table esta en una clase destinada para dicho


propsito, la para la tabla de smbolos implementa distintos mtodos
que ayudan a validar la semntica del programa:

Principales mtodos de la tabla dinmica:

Insertar: es utilizado para agregar una nueva entrada smbolo a la


tabla, recibe como parmetro el id y retorna un valor booleano
para indicar si fue posible su insercin (retorna falso si existe un
identificador igual).
Actualizar: es utilizado para agregar los atributos como el lexema,
tipo, valor, lnea, columna, funcin a la que pertenece y
parmetros (en caso de ser una funcin).
Buscar: es utilizado para buscar y retornar un lexema o id.

Anlisis Lexico
El anlisis lxico se basa en ir identificando todo lexema que se encuentra en el cdigo
fuente, si el lexema es vlido lo va aadiendo como token a la tabla de smbolos
identificando que es. (vase tabla de smbolos terminales).

Anlisis Sintactico

Gramticas
Reglas para las gramticas (P)
INICIO::= ESTRUCTURA;

ESTRUCTURA::= LIBRERIAS CONSTANTES ESTRUCT MEIN FUNCIONES


| LIBRERIAS CONSTANTES ESTRUCT MEIN
;

LIBRERIAS::= include libreria LIBRERIAS


;
CONSTANTES::= declare id VALOR CONSTANTES
;

ESTRUCT::= STRUCT id llave1 DECLARAR llave2 puntoComa ESTRUCT


;

VALOR::= validInt | validFloat | validString | validChar


;

MEIN::= VOID MAIN parentesis1 parentesis2 llave1 CUERPO llave2


| INT MAIN parentesis1 parentesis2 llave1 CUERPO RETORNANUM puntoComa llave2
| MAIN parentesis1 parentesis2 llave1 CUERPO llave2
;

RETORNANUM::= RETURN validInt


;

CUERPO::=
DECLARARESTRUCT SENTENCIAS
| DECLARAR DECLARARESTRUCT SENTENCIAS
| DECLARAR SENTENCIAS
| SENTENCIAS;

DECLARAR::= TIPOS LISTAVAR DECLARAR


| TIPOS LISTAVARASIG DECLARAR
| TIPOS VECTOR DECLARAR
| TIPOS VECTORASIG DECLARAR
| TIPOS LISTAVAR
| TIPOS LISTAVARASIG
| TIPOS VECTOR
| TIPOS VECTORASIG
;

TIPOS::= INT | CHAR | DOUBLE | FLOAT | LONG | SHORT ;

LISTAVAR::= id puntoComa | id coma LISTAVAR | id coma LISTAVARASIG


;

LISTAVARASIG::= id operadoresAsignacion EXP puntoComa | id operadoresAsignacion


EXP coma LISTAVARASIG
| id operadoresAsignacion EXP coma LISTAVAR
;

//Estructuras de datos
VECTOR::= id corchete1 validInt corchete2 puntoComa
| id corchete1 validInt corchete2 coma VECTOR
| id corchete1 validInt corchete2 coma VECTORASIG
| id corchete1 corchete2 operadoresAsignacion llave1 INICIALIZAV llave2 puntoComa
| id corchete1 corchete2 operadoresAsignacion llave1 INICIALIZAV llave2 coma
VECTOR
;

VECTORASIG::= id corchete1 validInt corchete2 operadoresAsignacion llave1


INICIALIZAV llave2
| id corchete1 validInt corchete2 operadoresAsignacion llave1 INICIALIZAV llave2 coma
VECTORASIG
| id corchete1 validInt corchete2 operadoresAsignacion llave1 INICIALIZAV llave2 coma
VECTOR
;

INICIALIZAV::= id | VALOR | id coma INICIALIZAV | VALOR coma INICIALIZAV ;

DECLARARESTRUCT::= STRUCT id LISTAESTRUCT puntoComa


| STRUCT id LISTAESTRUCT puntoComa DECLARARESTRUCT
;

LISTAESTRUCT::= id | id coma LISTAESTRUCT


;

ESTRUCTASIG::= id punto id operadoresAsignacion VALOR puntoComa


;

SENTENCIAS::= CICLOS SENTENCIAS


| LLAMADOFUNCIONES puntoComa SENTENCIAS
| ASIGNACIONES puntoComa SENTENCIAS
| CONDICIONAL SENTENCIAS
| SALIDAS SENTENCIAS
| ENTRADAS SENTENCIAS
| ESTRUCTASIG SENTENCIAS
|;

//Estructuras de control (repetitivas)


CICLOS::= WHILE parentesis1 LOGICO parentesis2 llave1 CUERPO llave2
| FOR parentesis1 ASIGFOR puntoComa LOGICO puntoComa INCREMENTO
parentesis2 llave1 CUERPO llave2
;

ASIGNACIONES::= id operadoresAsignacion EXP | id operadoresAsignacion


LLAMADOFUNCIONES | id corchete1 validInt corchete2 operadoresAsignacion EXP
| id operadoresAsignacion ENTRADACHAR
;

LOGICO::= TLOG AND LOGICO | TLOG OR LOGICO | TLOG


;
RELACIONAL::= TREL mayor TREL | TREL mayorIgual TREL |TREL igualIgual
TREL
| TREL menorIgual TREL | TREL menor TREL | TREL DIF TREL |TREL
;

TREL::= EXP | parentesis1 RELACIONAL parentesis2


;

TLOG::= NOT RELACIONAL | RELACIONAL | parentesis1 LOGICO parentesis2


;

EXP::= TERMINO mas EXP | TERMINO | TERMINO menos EXP ;

TERMINO::= FACTOR mul TERMINO | FACTOR div TERMINO | FACTOR mod


TERMINO | FACTOR ;

FACTOR::= VALOR | id | parentesis1 EXP parentesis2 ;

ASIGFOR::= TIPOS ASIGVARFOR | ASIGVARFOR ;

ASIGVARFOR::= id operadoresAsignacion VALOR ;

INCREMENTO::= id mas mas | id menos menos | id operadoresAsignacion EXP ;

LLAMADOFUNCIONES::= id parentesis1 PARAMETROS parentesis2 | id parentesis1


parentesis2 ;

//Estructuras de control (condicionales)


CONDICIONAL ::= CONDIF | CONDSWITCH ;

CONDIF::= IF parentesis1 LOGICO parentesis2 llave1 CUERPO llave2 ELSE llave1


CUERPO llave2
| IF parentesis1 LOGICO parentesis2 llave1 CUERPO llave2
| IF parentesis1 LOGICO parentesis2 llave1 CUERPO RETURN VALOR puntoComa
llave2 ELSE llave1 CUERPO RETURN VALOR puntoComa llave2
| IF parentesis1 LOGICO parentesis2 llave1 CUERPO RETURN VALOR puntoComa
llave2
;

CONDSWITCH::=
SWITCH parentesis1 validInt parentesis2 llave1 CASESWITCH llave2 ;

CASESWITCH::= CASE validInt dosPuntos CUERPO BREAK puntoComa


CASESWITCH
| DEFAULT dosPuntos CUERPO
;
FUNCIONES::= id parentesis1 parentesis2 llave1 CUERPO llave2
| TIPOS id parentesis1 parentesis2 llave1 CUERPO RETURN VALOR puntoComa llave2
| TIPOS id parentesis1 DEFPARAMETROS parentesis2 llave1 CUERPO RETURN
VALOR puntoComa llave2
| VOID id parentesis1 parentesis2 llave1 CUERPO llave2
| VOID id parentesis1 DEFPARAMETROS parentesis2 llave1 CUERPO llave2
| id parentesis1 DEFPARAMETROS parentesis2 llave1 CUERPO llave2
| id parentesis1 parentesis2 llave1 CUERPO llave2 FUNCIONES
| TIPOS id parentesis1 parentesis2 llave1 CUERPO RETURN VALOR puntoComa llave2
FUNCIONES
| TIPOS id parentesis1 DEFPARAMETROS parentesis2 llave1 CUERPO RETURN
VALOR puntoComa llave2 FUNCIONES
| VOID id parentesis1 parentesis2 llave1 CUERPO llave2 FUNCIONES
| VOID id parentesis1 DEFPARAMETROS parentesis2 llave1 CUERPO llave2
FUNCIONES
| id parentesis1 DEFPARAMETROS parentesis2 llave1 CUERPO llave2 FUNCIONES
;

PARAMETROS::= id | VALOR | id coma PARAMETROS | VALOR coma


PARAMETROS;

DEFPARAMETROS::= TIPOS id DEFPARAMETROS2;

DEFPARAMETROS2 ::= coma DEFPARAMETROS


;

TIPODATO::= validTipoInt | validTipoFloat | validTipoChar | validTipoString ;

//Estructuras de Salida

SALIDAS::= SALIDACHAR | SALIDAPRINTF ;

SALIDACHAR::= PUTCHAR parentesis1 DATOSALIDACHAR parentesis2 puntoComa


;

DATOSALIDACHAR::= validInt | validChar | id;

SALIDAPRINTF::=
PRINTF parentesis1 CONTENIDOPRINTF parentesis2 puntoComa
;

CONTENIDOPRINTF::= validString | TIPODATO coma VALOR | TIPODATO coma id


;

//Estructuras de Entrada

ENTRADAS::= ENTRADACHAR | ENTRADASCANF;


ENTRADACHAR::= GETCHAR parentesis1 parentesis2 puntoComa
;

ENTRADASCANF::=
SCANF parentesis1 DATOENTRADASCANF parentesis2 puntoComa
;

DATOENTRADASCANF::= TIPODATO coma id


;

Smbolos terminales (T)


NUM INT AUTO BREAK CASE CHAR

CONST CONTIN DEFAULT DO DOUBLE ELSE


UE

ENUM EXTERN FLOAT FOR GOTO IF

LONG REGISTE RETURN SHORT SIGNED SIZEOF


R

STATIC STRUCT SWITCH TYPEDEF UNION UNSIGNE


D

VOID VOLATIL WHILE INCLUDE DEFINE MAIN


E

DIF OR AND NOT STAR error2

validString id cadenas validChar validInt validFloat

operadoresAsig mas menos mul div mod


nacion

include declare comillaDo menorIgu mayorIgua igualIgual


ble al l

operadoresEspe comenta parentesi parentesis mayor menor


ciales rios s1 2

llave1 llave2 coma puntoCom dosPuntos punto


a
corchete1 corchete apostrofe libreria PUTCHAR GETCHAR
2

PRINTF SCANF validTipoI validTipoC validTipoSt validTipoFl


nt har ring oat

Smbolos no terminales (N)


INICIO ESTRUCTURA LIBRERIAS CONSTANTE ESTRUCT ASIGNA
S

VALOR MEIN CUERPO op_l DECLARAR LISTAVAR

LISTAVARASI VECTOR VECTORASI DECLARARES LISTAESTRU ASIGNACIO


G G TRUCT CT NES

ESTRUCTASIG SENTENCIAS CICLOS LOGICO LOGICOAUX TLOG

RELACIONAL INICIALIZAV RELACIONA TREL EXP EXPAUX


LAUX

TERMINO TERMINOAUX FACTOR ASIGFOR ASIGVARFO INCREMENT


R O

LLAMADOFUN TIPOS PARAMETR CONDICIONA CONDIF operadoresR


CIONES OS L elacionales

CONDSWITCH CASESWITCH FUNCIONE DEFPARAMET DEFPARAME RETORNANU


S ROS TROS2 M

SALIDACHAR DATOSALIDAC ENTRADAC SALIDAPRIN CONTENIDO TIPODATO


HAR HAR TF PRINTF

ENTRADASCA DATOENTRAD ENTRADAS SALIDAS


NF ASCANF

Regla inicial (S)


INICIO::=

Gramticas de atributos
Para obtener los atributos dentro de las gramticas que rigen el
comportamiento, cada no terminal que se encuentre en estas guarda la
informacin del subrbol que este genere, el subrbol es generado por
los no terminales que estn implcitos en la gramtica.
Los atributos van subiendo por el rbol desde los terminales en las
gramticas ms bajas hasta los no terminales ms generales.

Anlisis Semntico
Manejador de errores semnticos
El manejador de errores utilizado en el anlisis lxico y sintctico, es el
mismo que emplea el semntico, en dicho manejador guardamos en
forma de tabla la siguiente informacin:

Tipo (Si es lxico, semntico, o sintctico).


Valor (Smbolo que causa el error)
Lnea del error
Columna del error

Para su implementacin hacemos uso de una clase en Java con lo


mencionado anteriormente:
public class errorsin {
String tipo,valor;
int linea, columna;

errorsin(String Tipo,int yyline,int yycolumn,String yytext){


tipo=Tipo;
linea=yyline+1;
columna=yycolumn+1;
valor=yytext;
}

public String toString(){


switch(tipo){
case "Sintactico":
return "Error en linea: "+linea+". La estructura de la
sentencia no es adecuada. Conflicto cerca de \""+ valor+"\"";
case "Lexico":
return "Error en linea: "+linea+". No se esperaba el
valor: "+"\""+valor+"\"";
case "id_noexiste":
return "Error en linea: "+linea+". El id "+"\""+valor+"\"
no existe";
case "Irrecuperable":
return "";//"IRRECUPERABLE!["+linea+","+columna+"]";
case "SinSem":
return "Error en linea "+(linea+1)+". "+valor;
case "ES":
return "Error en linea "+(linea+1)+". "+valor;
default:
return valor;
}
}
}

La clase anterior hace uso de un constructor para asignar los atributos a


la clase error, de igual forma esta clase se compone de una funcin
llamado toString, este mtodo cuenta con un switch que toma como
condicin el tipo del error, su funcin principal es la de retornar la
posicin de error junto con un mensaje en tipo String. Su
implementacin es dentro de las gramticas (en el archivo cup) como se
muestra en el siguiente ejemplo

SCANF error:e DATOENTRADASCANF parentesis2 puntoComa


{:parser.ManejadorDeErrores.add(new errorsin("ES",eleft-
1,eright,"La estructura es incorrecta. No se encontr el
parentesis de apertura."));:}

La declaracin de variable no es restringida al primer momento en que


se detecta, estas son agregadas a la tabla de smbolos. Ya que fueron
agregados un procedimiento verifica si hay repeticin de variables, en
caso de encontrar alguna incongruencia en la tabla de smbolos,
muestra las variables duplicadas, la duplicidad se verifica por el nombre
de la variable sin importar su tipo.

En el caso de la utilizacin de variables en las distintas sentencias, estas


son verificadas en la tabla de smbolos, en caso de existir, se contina
con el proceso. De lo contrario, se dispara el error correspondiente.
Una vez que las variables son utilizadas en expresiones de asignacin u
otro tipo, se efecta una sntesis de datos para verificar la
compatibilidad. La sntesis de tipos se genera localizando los terminales
ubicados en los ms bajo del rbol. En caso de que los tipos no
coincidan en su declaracin se dispara un error de incompatibilidad de
tipos. El compilador no efecta la transformacin de tipos necesaria o
requerida, esta se tiene que hacer manualmente por el usuario.

Al momento de asignar el resultado de una expresin, esta debe ser


compatible en el tipo a donde se pretende asignar. En caso de no serlo,
puede deberse a dos opciones:
1. La consecuencia de la expresin es un error y, un error no es
asignable a ningn tipo de dato.
2. La asignacin directa o consecuente de la expresin es una tipo
de dato valido. Sin embargo, este sigue siendo incompatible para
la asignacin.
De igual manera sucede al momento de asignar un valor constante.

Comprobacion de tipos
La aplicacin de los operadores y operandos deben ser compatibles,
para la aplicacin de este anlisis se hizo uso de las clases mencionadas
anteriormente como lo es la tabla de smbolos y el manejador de
errores, tambin se implementa un mtodo encargado de comprobar la
compatibilidad, este mtodo recibe tres parmetros que son: operando
uno, operando dos y el operador.

El siguiente segmento de cdigo muestra su implementacin para la


expresin de una suma, donde termino es el operando uno, mas es el
operador y exp es el operando dos.

EXP::= TERMINO:f mas:op EXP:t {:


...
String evaluacion =
parser.evalTipo(f.toString().split(",")[0],t.toString().
split(",")[0],op.toString());
...
:}

Comprobaciones de unicidad
La declaracin de funciones, variables, constantes y otros objetos debe
ser nica, para la aplicacin de este anlisis se hizo uso de las clases
mencionadas anteriormente como lo es el manejador de errores y tabla
de smbolos, esta ltima cuenta con un mtodo de insertar que al
detectar un error de unicidad antes de la insercin regresa un valor falso
lo cual provoca que se muestre el error.
El siguiente segmento de cdigo muestra su implementacin para la
expresin de una asignacin.

LISTAVARASIG::= id:miId operadoresAsignacion:op EXP puntoComa


{:
RESULT=parser.insertarTipo(miId+"",parser.tipoActual+"",
parser.valorActualTipo+"",parser.valorActual+"",
miIdleft,miIdright,"","");
...

Donde insertarTipo es una funcin encargada de dicho anlisis.

Cdigo Intermedio
En el modelo de anlisis y sntesis de un compilador, la etapa inicial traduce un
programa fuente a una representacin intermedia a partir de la cual la etapa final
genera el cdigo objeto. Los detalles del lenguaje objeto se confinan en la etapa final,
si esto es posible. Aunque un programa fuente se puede traducir directamente al
lenguaje objeto, algunas ventajas segn Ruz (2008) de utilizar una forma intermedia
independiente de la mquina son:

1. Se facilita la re destinacin; se puede crear un compilador para una mquina


distinta uniendo una etapa final para la nueva mquina a una etapa inicial ya
existente.
2. Se puede aplicar a la representacin intermedia un optimizador de cdigo
independiente de la mquina.

La generacin de cdigo en ensamblador puede ser muy difcil es por esto que se suele
crear un paso intermedio para reducir un poco la complejidad. En esta fase se crean
una serie de instrucciones en un pseudolenguaje, que permitir a partir de l, generar
el cdigo final (en ensamblador) de una manera ms sencilla. Este pseudolenguaje
debe ser independiente de la plataforma. Es decir, independiente del ensamblador de
la mquina. Y se hace as por dos cosas: por ser una manera de preparar nuestro
compilador para cualquier plataforma y por simplificar un poco el trabajo de crear
directamente nuestro programa en ensamblador.
A este pseudolenguaje se le llama cdigo intermedio.

Cdigo de tres direcciones


El cdigo de tres direcciones tiene su origen en la necesidad de gestionar las
expresiones del lenguaje (sumas, restas etc...).
Cuando tenemos una expresin, generalmente consta del nombre de la expresin, los
dos operandos y el resultado.

Debemos saber, adems, que vamos a escribir y leer sobre la memoria del computador
(en sus direcciones de memoria). Por lo tanto, vamos a utilizar las direcciones de
memoria para guardar valores de los resultados de las operaciones. Por ejemplo, si
queremos hacer la suma de dos nmeros, primero debemos guardar cada nmero en
una direccin de memoria, y luego aplicar la operacin suma entre esas direcciones de
memoria y el resultado, lo guardamos en otra direccin de memoria. Es decir,
utilizamos tres direcciones y el nombre de la operacin.

Esquemas de generacin
Los esquemas de generacin son las estrategias o acciones que se debern realizarse y
tomarse en cuenta en el momento de generar cdigo intermedio. Los esquemas de
generacin dependen de cada lenguaje.

Variables y constantes
Se crean entradas para cada variables segn su tipo
Reserva de espacio en funcin del tiempo empleado.
Posibilidades:
Estricta (lugar es una memoria)
lugar es un texto

Expresiones
Para generar expresiones estas deben representarse de manera ms simple y ms
literal para que su conversin sea ms rpida.
Por ejemplo la traduccin de operaciones aritmticas debe especificarse una por una,
de tal forma que una expresin sea lo ms mnimo posible.

Estatuto de asignacin
Las operaciones de asignacin deben quedar expresadas por una expresin sencilla, si
est es compleja se debe reducir hasta quedar un operador sencillo. Por ejemplo: x =
a+b/5; debe quedar de la forma y = b / 5; z = a + y; x = z.

Estatuto condicional
Las condiciones deben expresarse de manera lo ms sencilla posible de tal forma que
puedan evaluarse en cortocircuito.
Las instrucciones de decisin compleja como switch se reducen a una versin
complejas de ifs.

Estatuto de ciclos
Los ciclos se descomponen en un ciclo genrico, por lo que ciclos while, for y dowhile
tienen la misma representacin interna. En el caso de C, todo queda en forma de
while.
Las condiciones lgicas tambin pueden ser evaluadas en cortocircuito y reducidas.
Generacin de cdigo intermedio en JABA Compiler

Para JABA Compiler, como se mencion anteriormente se seleccion el cdigo de tres


direcciones, porque es muy parecido al ensamblador, por lo que la conversin del
cdigo intermedio a cdigo objeto resultar ms fcil que si usramos, por ejemplo,
tripletas o cudruplos.

Cmo se implementa en JABA Compiler?

1. Se cre una clase llamada GenIntermedio en la cual estn los mtodos que
reciben valores provenientes del analizador sintctico (CUP) .
2. En la clase GenIntermedio se crea una variable de tipo cadena, en la cual se
van concatenando las diferentes acciones segn sea la operador o instruccin
que recibe como parmetro. Por ejemplo:

case ("<") :
cadCodigo = cadCodigo+" if(" + e1 + " < " + e2 + ") goto " + resultado
+ "; \n";
break;

3. Se sintetizan los valores de las gramticas (utilizando RESULT y slo en caso de


ser necesario) y enseguida se envan los mismos a la clase de generacin de
cdigo.

Ejemplo:
IMPRIMIR::= PRINT parentesis1 EXPRESION:e parentesis2 puntoComa {:

GenIntermedio.genCodigo("PRINT",null,null,e+"");

:}|

4. Se compara el operador o instruccin que recibe de parmetro a travs de un


Switch para determinar qu accin ser la que se realizar.
5. Se concatenan los valores recibidos a una cadena la instruccin con formato de
cdigo de tres direcciones.

En el lado derecho de la pantalla principal, est un espacio en donde est escrito el


cdigo intermedio generado.

Cabe destacar que nicamente se genera cuando no existe algn tipo de error. En caso
de existir; se queda en pantalla el cdigo intermedio del ltimo cdigo fuente correcto
que fue ingresado.
Gramticas en Cdigo Intermedio:
Algunas gramticas fueron modificadas para que se pueda realizar la generacin de
cdigo intermedio, como hacer que tengan de nuevo recursin por izquierda, sin
embargo el funcionamiento del analizador no se ve afectado.

Enseguida se presentan las gramticas y las llamadas a los mtodos de creacin de


cdigo intermedio.

Incremento: En este caso solamente le asignamos a una variable el resultado de la


suma de la misma ms 1.

Ejemplo:

J= J+1

INCREMENTO::= id:ID masMas {:

boolean esta = Tabla_Simbolos.buscarSimbolo(ID+"");

if(esta==false){

VPrincipal.escribirOutput("Error en la linea "+(IDleft+1)+ ":


Variable '"+ID+""+"' no ha sido declarada "+"\n" );

String t = GenIntermedio.genTemp();

GenIntermedio.genCodigo("+", ID+"", "1", ID+"");

RESULT = t;

:};

Decremento: Se le asigna a una variable el resultado de la suma de la misma ms 1.

Ejemplo:

J= J-1

DECREMENTO::= id:ID menosMenos{:

boolean esta = Tabla_Simbolos.buscarSimbolo(ID+"");

if(esta==false){
VPrincipal.escribirOutput("Error en la linea "+(IDleft+1)+ ":
Variable '"+ID+""+"' no ha sido declarada "+"\n" );

String t = GenIntermedio.genTemp();

//GenIntermedio.genCodigo("asig", ID+"", null, t);

GenIntermedio.genCodigo("-",
ID+"", "1", ID+"");

RESULT = t;

:};

Estructuras condicionales:

Se hace uso de una clase llamada ECondicin para el manejo de los posibles resultados
de una estructura condicional: cierto o falso. Estos resultados tienen asignada una
etiqueta, que es haca donde el flujo de ejecucin segn sea el caso (si la condicin es
verdadera o si es falsa).

En el caso especfico del switch se comparan los casos con el valor de la variable del
switch, si es el resultado de la condicin es falso se hace un salto al siguiente caso y
as sucesivamente hasta llegar al default y si el resultado es verdadero en algn caso,
permite saltarse todos los dems.

COND::= COND_LOG:c {:RESULT = c;:} | COND_AND:c {:RESULT = (ECondicion)


c;:} | COND_OR:c {:RESULT = (ECondicion) c;:} ;

COND_AND::= COND_LOG:c1{:

GenIntermedio.genCodigo("LABEL", null, null, c1.ver());

:} AND COND_LOG:c2{:

GenIntermedio.genCodigo("LABEL", null, null, c1.falso());

GenIntermedio.genCodigo("GOTO", null, null, c2.falso());

RESULT = new ECondicion(c2.ver(), c2.falso());

parser.id1 = parser.esId;

:} MASCOND;

MASCOND::= AND COND_LOG:c {:


System.out.println(c.ver()+" "+c.falso());

GenIntermedio.genCodigo("LABEL", null, null, c.ver());

:} MASCOND {: GenIntermedio.genCodigo("LABEL", null, null, c.falso()); :} |

OR COND_LOG:c {:

GenIntermedio.genCodigo("LABEL", null, null, c.falso());

:}MASCOND| ;

COND_OR::= COND_LOG:c1 OR {:

GenIntermedio.genCodigo("LABEL", null, null, c1.falso());

:}COND_LOG:c2 {:

GenIntermedio.genCodigo("LABEL", null, null, c1.ver());

GenIntermedio.genCodigo("GOTO", null, null, c2.ver());

RESULT = new ECondicion(c2.ver(), c2.falso());

:} MASCOND;

COND_LOG::= EXPRESION:e1{:parser.id1 = parser.esId;:} mayor:M


EXPRESION:e2 {:

String v = GenIntermedio.genLabel();

String f = GenIntermedio.genLabel();

GenIntermedio.genCodigo(">", e1+"", e2+"", v);

GenIntermedio.genCodigo("GOTO", null,
null, f);

if(parser.id1){

Tabla_Simbolos.condID(e1+"",M+"",e2+"",parser.esId,parser.accion);

else{
Tabla_Simbolos.condCon(M+"",e2+"",parser.esId,parser.accion);

RESULT = new ECondicion(v, f);

:}

|EXPRESION:e1{:parser.id1 = parser.esId;:} menor:M EXPRESION:e2{:

String v = GenIntermedio.genLabel();

String f = GenIntermedio.genLabel();

GenIntermedio.genCodigo("<", e1+"", e2+"", v);

GenIntermedio.genCodigo("GOTO", null,
null, f);

if(parser.id1){

Tabla_Simbolos.condID(e1+"",M+"",e2+"",parser.esId,parser.accion);

else{

Tabla_Simbolos.condCon(M+"",e2+"",parser.esId,parser.accion);

RESULT = new ECondicion(v, f);

:}

|EXPRESION:e1{:parser.id1 = parser.esId;:} mayorIgual:M


EXPRESION:e2{:

String v = GenIntermedio.genLabel();

String f = GenIntermedio.genLabel();

GenIntermedio.genCodigo(">=", e1+"", e2+"", v);

GenIntermedio.genCodigo("GOTO", null,
null, f);

if(parser.id1){
Tabla_Simbolos.condID(e1+"",M+"",e2+"",parser.esId,parser.accion);

else{

Tabla_Simbolos.condCon(M+"",e2+"",parser.esId,parser.accion);

RESULT = new ECondicion(v, f);

:}

|EXPRESION:e1{:parser.id1 = parser.esId;:} menorIgual:M


EXPRESION:e2{:

String v = GenIntermedio.genLabel();

String f = GenIntermedio.genLabel();

GenIntermedio.genCodigo("<=", e1+"", e2+"", v);

GenIntermedio.genCodigo("GOTO", null,
null, f);

if(parser.id1){

Tabla_Simbolos.condID(e1+"",M+"",e2+"",parser.esId,parser.accion);

else{

Tabla_Simbolos.condCon(M+"",e2+"",parser.esId,parser.accion);

RESULT = new ECondicion(v, f);

:}

|EXPRESION:e1{:parser.id1 = parser.esId;:} igualIgual:M


EXPRESION:e2 {:

String v = GenIntermedio.genLabel();

String f = GenIntermedio.genLabel();
GenIntermedio.genCodigo("==", e1+"", e2+"", v);

GenIntermedio.genCodigo("GOTO", null,
null, f);

if(parser.id1){

Tabla_Simbolos.condID(e1+"",M+"",e2+"",parser.esId,parser.accion);

else{

Tabla_Simbolos.condCon(M+"",e2+"",parser.esId,parser.accion);

RESULT = new ECondicion(v, f);

:}|

EXPRESION:e1 {:parser.id1 = parser.esId;:}DIF:M EXPRESION:e2{:

String v = GenIntermedio.genLabel();

String f = GenIntermedio.genLabel();

GenIntermedio.genCodigo("!=", e1+"", e2+"", v);

GenIntermedio.genCodigo("GOTO", null,
null, f);

if(parser.id1){

Tabla_Simbolos.condID(e1+"",M+"",e2+"",parser.esId,parser.accion);

else{

Tabla_Simbolos.condCon(M+"",e2+"",parser.esId,parser.accion);

RESULT = new ECondicion(v, f);

:}|

parentesis1 COND:c {: RESULT = c; :} parentesis2;


EIF::= IF2:et parentesis1 COND:c {:

GenIntermedio.genCodigo("LABEL",null,null,c.ver());

:}parentesis2 llave1 BODYMAIN llave2{:

String fin = GenIntermedio.genLabel();

et.fin(fin);

GenIntermedio.genCodigo("GOTO", null, null, et.fin());

GenIntermedio.genCodigo("LABEL", null, null, c.falso());

:} EIF_ELSE{:

GenIntermedio.genCodigo("LABEL", null, null, et.fin());

:}

EIF_ELSE::= ELSE llave1 BODYMAIN llave2 |;

IF2::= IF:et{:

RESULT = new IniFin(null, null);

:};

ESWITCH::= SWITCH{:

parser.switchLabel = GenIntermedio.genLabel();

:} parentesis1 id:ID{:parser.id = ID;:} parentesis2 llave1 MASCASE DEF{:

parser.id = ID+"";

GenIntermedio.genLabel();

Tabla_Simbolos.valSwitch(ID+"",parser.valCase,parser.esId,parser.valAccion);

GenIntermedio.genCodigo("LABEL",null,null,parser.switchLabel) ;
:} llave2

//|SWITCH error:s id:ID parentesis2 llave1 MASCASE DEF llave2 {:


VPrincipal.escribirOutput("Error: Smbolo '(' esperado en la lnea "+(sleft+1)+"\n"); :}

//|SWITCH parentesis1 id:ID error:s llave1 MASCASE DEF llave2 {:


VPrincipal.escribirOutput("Error: Smbolo ')' esperado en la lnea "+(sleft+1)+"\n"); :}

DEF::=DEFAULT dosPuntos BODYMAIN BREAK puntoComa MASCASE| ;

CASOS::= CASE{:

RESULT= GenIntermedio.genLabel();

:} VALUE:VA dosPuntos{:

parser.label = GenIntermedio.genLabel();

// String t = GenIntermedio.genTemp();

GenIntermedio.genCodigo("iffalse", VA+"", parser.id,parser.label);

:} BODYMAIN BREAK puntoComa{:

GenIntermedio.genCodigo("GOTO", null, null, parser.switchLabel);

GenIntermedio.genCodigo("LABEL", null, null, parser.label);

:} MASCASE ;

VALUE::=VALOR:VA {: Tabla_Simbolos.putLine((VAleft+1));
parser.valAccion=parser.valAccion+parser.accion+",";
parser.valCase=parser.valCase+parser.valor+","; RESULT = VA; :}|

id:ID {: Tabla_Simbolos.putLine((IDleft+1));
parser.valAccion=parser.valAccion+"ID"+",";parser.esId=true; :};

MASCASE::= CASOS |;
Estructuras repetitivas:

Se utiliz una clase llamada Inifin, que de una manera similar al caso de las
estructuras condicionales, se utiliza para el manejo de las etiquetas, pero, en este
caso, para indicar el inicio y el final de un ciclo.

Las etiquetas son utilizadas en las estructuras repetitivas para que el flujo de ejecucin
regrese al inicio del ciclo para que de sta forma se ejecuten ciertas sentencias
determinado nmero de veces, hasta que una condicin haga que termine el ciclo y se
produzca un salto a una etiqueta externa al ciclo.

//ESTRUCTURAS REPTITIVAS

EWHILE::= WHILE2:et {:

GenIntermedio.genCodigo("LABEL", null, null, et.ini());

:} parentesis1 COND:c {:

GenIntermedio.genCodigo("LABEL", null, null, c.ver());

:}parentesis2 llave1 BODYMAIN{:

GenIntermedio.genCodigo("GOTO", null, null, et.ini());

GenIntermedio.genCodigo("LABEL", null, null, c.falso());

:} llave2

| WHILE2 error:S COND parentesis2 llave1 BODYMAIN llave2


{:VPrincipal.escribirOutput("Error: smbolo '(' esperado en la linea
"+(Sleft+1)+"\n");:}

//| WHILE2 parentesis1 COND error:s llave1 BODYMAIN llave2


{:VPrincipal.escribirOutput("Error: smbolo ')' esperado en la linea
"+(sleft+1)+"\n");:}

| error:s parentesis1 COND parentesis2 llave1 BODYMAIN llave2


{:VPrincipal.escribirOutput("Error: smbolo '{' esperado en la linea
"+(sleft+1)+"\n");:}

;
WHILE2::= WHILE:et{:

String ini = GenIntermedio.genLabel();

String fin = GenIntermedio.genLabel();

RESULT = new IniFin(ini,fin);

:};

FOR2::= FOR:et {:

String ini = GenIntermedio.genLabel();

String fin = GenIntermedio.genLabel();

RESULT = new IniFin(ini,fin);

:};

EFOR::= FOR2:et {:

GenIntermedio.genCodigo("LABEL", null, null, et.ini());

:} parentesis1 ESP1 COND:c puntoComa {:

GenIntermedio.genCodigo("LABEL", null, null, et.fin());

:} ESP2 parentesis2 {:

GenIntermedio.genCodigo("GOTO", null, null, et.ini());

GenIntermedio.genCodigo("LABEL", null, null, c.ver());

:}llave1 BODYMAIN {:

GenIntermedio.genCodigo("GOTO", null, null, et.fin());

GenIntermedio.genCodigo("LABEL", null, null, c.falso());

:}llave2;

ESP1::= id puntoComa| ASIGNACION puntoComa | VARI;


ESP2::= ASIGNACION puntoComa| DECREMENTO | INCREMENTO;

Estructuras de salida

Para la impresin de cadenas solamente se toma la cadena y en cdigo de tres


direcciones se mostrar print ms la cadena extrada del cdigo fuente:

Ejemplo:

System.out.print(hola);

Convertido:

print hola;

IMPRIMIR::= PRINT parentesis1 EXPRESION:e parentesis2 puntoComa {:

GenIntermedio.genCodigo("PRINT",null,null,e+"");

:}|

PRINTLN parentesis1 EXPRESION:e parentesis2 puntoComa {:

GenIntermedio.genCodigo("PRINT",null,null,e+"");

:}

Entrada de datos:

Se hace una asignacin a una variable indicando que se va a recibir una cadena:

X = recibir cadena

SCN2::= id:ID operadoresAsignacion id NEXTN parentesis1 parentesis2 puntoComa{:


boolean esta = Tabla_Simbolos.buscarSimbolo(ID+""); if(esta==false){

VPrincipal.escribirOutput("Error en la linea "+(IDleft+1)+ ": Variable


"+ID+""+" no ha sido declarada "+"\n" );

} else{

System.out.println("Aqui estooy");

GenIntermedio.genCodigo("asig","Recibir cadena",null,ID+""); }

:}
Asignaciones:

Para asignar un valor a una variable resultado de operaciones aritmticas se van


sintetizando mediante el uso del RESULT los valores en la gramtica de expresin. Las
operaciones entre dos operandos se guarda en una temporal y esa misma temporal se
utiliza para hacer las operaciones si es necesario. Cuando ya no hay ms operaciones
que hacer se le asigna la ltima temporal a una variable.

Ejemplo

F = 5+ x +4;

t0 := 5 + x;

t1:= t0 + 4;

F= t1

//Asignacin

ASIGNACION ::= id :ID operadoresAsignacion EXPRESION:exp {:

Tabla_Simbolos.putLine((IDleft+1));

Tabla_Simbolos.insertaValor(ID+"",parser.valor,parser.esId,parser.accion);

GenIntermedio.genCodigo("asig",exp+"",null,ID);

:}

| error:s operadoresAsignacion EXPRESION {: VPrincipal.escribirOutput("Error


en la lnea "+(sleft+1)+" Identificador esperado \n" ); :}

|id error:s operadoresAsignacion EXPRESION {:


VPrincipal.escribirOutput("Error en la lnea "+(sleft+1)+" Estructura invlida antes del
identificador y smbolo '=' \n" ); :}

EPRESION::= EXPRESION:e1 {: parser.id1 = parser.esId; parser.e1 = parser.valor;

:} mas TERM:e2 {:
String t = GenIntermedio.genTemp();

GenIntermedio.genCodigo("+",e1+"",e2+"",t);

RESULT = t;

:}

| EXPRESION:e1 menos TERM:e2 {:

String t = GenIntermedio.genTemp();

GenIntermedio.genCodigo("-",e1+"",e2+"",t);

RESULT = t;

:}

| TERM:e2{:

RESULT = e2;

:} ;

TERM ::= TERM:e1 STAR FACT:e2 {:

String t = GenIntermedio.genTemp();

GenIntermedio.genCodigo("*",e1+"",e2+"",t);

RESULT = t;

:}

| TERM:e1 div {: parser.id1 = parser.esId; :} FACT:e2 {:

String t = GenIntermedio.genTemp();

GenIntermedio.genCodigo("/",e1+"",e2+"",t);

RESULT = t;
:}

| FACT:e1 {:

RESULT = e1;

:};

FACT ::= menos FACT

| id:ID{:

parser.valor=ID;

parser.esId=true;

RESULT = ID;

:}

| VALOR:VA {:

RESULT = VA;

parser.valor=VA+"";

:}

| parentesis1 EXPRESION:e1 parentesis2 {:

RESULT = e1;

:};
BIBLIOGRAFA
Schildt, H. (2014). Java a beginner's guide. New York: McGraw-
Hill Osborne.

Garca, A. Arranz, J. (2007). Programacin Orientada a Objetos


con Java. Madrid, Espaa: ETSII-UPM.

Dalle, N. Joyce, D. Weems, C. (2002). Object-Oriented Data


Structures using Java [Estructuras de Datos Orientadas a
Objetos]. Sudbury, Massachusetts: Jones and Bartlett
Publishers.

Ladrn J. (2010). Fundamentos de Programacin en Java.


Madrid, Espaa: EME.

Aho, A. Lam M. Sethi, R. Ullman, J.. (2008). Compiladores.


Principios, tcnicas y herramientas. Mxico: PEARSON
EDUCACIN.

Ruz, J.. (2008). Compiladores: Teora Y Prctica Con Java, Jlex,


Cup Y Ens2001. Londres:

Olivares, J.. (2012). Unidad VI Generacin de Cdigo


Intermedio. octubre 29, 2015, de Sistema Internacional
Superior Tecnolgica Sitio web:
http://dsc.itmorelia.edu.mx/~jcolivares/courses/ps207a/ps2_u6
.pdf

Franco G. (2000). Programacin en Lenguaje Java. Octubre 05,


2015. Sitio web:
http://www.sc.ehu.es/sbweb/fisica/cursoJava/fundamentos/intr
oduccion/primero.htm

Snchez J. (2004). Java2. octubre 03, 2015, de Snchez Sitio


web: http://jorgesanchez.net/programacion/manuales/Java.pdf
Lengua Viva. (2011). Aplicaciones de la Programacin Java.
Octubre,08,2015, de Logo Sitio web:
http://www.lenguaviva.es/aplicaciones-de-la-programacin-java

You might also like