Professional Documents
Culture Documents
Lenguajes y Automatas II
Manual Tecnico: Lenguaje GOS.
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.
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;
CUERPO::=
DECLARARESTRUCT SENTENCIAS
| DECLARAR DECLARARESTRUCT SENTENCIAS
| DECLARAR SENTENCIAS
| SENTENCIAS;
//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
;
CONDSWITCH::=
SWITCH parentesis1 validInt parentesis2 llave1 CASESWITCH llave2 ;
//Estructuras de Salida
SALIDAPRINTF::=
PRINTF parentesis1 CONTENIDOPRINTF parentesis2 puntoComa
;
//Estructuras de Entrada
ENTRADASCANF::=
SCANF parentesis1 DATOENTRADASCANF parentesis2 puntoComa
;
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:
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.
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.
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:
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.
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
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;
Ejemplo:
IMPRIMIR::= PRINT parentesis1 EXPRESION:e parentesis2 puntoComa {:
GenIntermedio.genCodigo("PRINT",null,null,e+"");
:}|
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.
Ejemplo:
J= J+1
if(esta==false){
String t = GenIntermedio.genTemp();
RESULT = t;
:};
Ejemplo:
J= J-1
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;
:};
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_AND::= COND_LOG:c1{:
:} AND COND_LOG:c2{:
parser.id1 = parser.esId;
:} MASCOND;
OR COND_LOG:c {:
:}MASCOND| ;
COND_OR::= COND_LOG:c1 OR {:
:}COND_LOG:c2 {:
:} MASCOND;
String v = GenIntermedio.genLabel();
String f = GenIntermedio.genLabel();
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);
:}
String v = GenIntermedio.genLabel();
String f = GenIntermedio.genLabel();
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);
:}
String v = GenIntermedio.genLabel();
String f = GenIntermedio.genLabel();
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);
:}
String v = GenIntermedio.genLabel();
String f = GenIntermedio.genLabel();
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);
:}
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);
:}|
String v = GenIntermedio.genLabel();
String f = GenIntermedio.genLabel();
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);
:}|
GenIntermedio.genCodigo("LABEL",null,null,c.ver());
et.fin(fin);
:} EIF_ELSE{:
:}
IF2::= IF:et{:
:};
ESWITCH::= SWITCH{:
parser.switchLabel = GenIntermedio.genLabel();
parser.id = ID+"";
GenIntermedio.genLabel();
Tabla_Simbolos.valSwitch(ID+"",parser.valCase,parser.esId,parser.valAccion);
GenIntermedio.genCodigo("LABEL",null,null,parser.switchLabel) ;
:} llave2
CASOS::= CASE{:
RESULT= GenIntermedio.genLabel();
:} VALUE:VA dosPuntos{:
parser.label = GenIntermedio.genLabel();
// String t = GenIntermedio.genTemp();
:} 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 {:
:} parentesis1 COND:c {:
:} llave2
;
WHILE2::= WHILE:et{:
:};
FOR2::= FOR:et {:
:};
EFOR::= FOR2:et {:
:} ESP2 parentesis2 {:
:}llave1 BODYMAIN {:
:}llave2;
Estructuras de salida
Ejemplo:
System.out.print(hola);
Convertido:
print hola;
GenIntermedio.genCodigo("PRINT",null,null,e+"");
:}|
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
} else{
System.out.println("Aqui estooy");
GenIntermedio.genCodigo("asig","Recibir cadena",null,ID+""); }
:}
Asignaciones:
Ejemplo
F = 5+ x +4;
t0 := 5 + x;
t1:= t0 + 4;
F= t1
//Asignacin
Tabla_Simbolos.putLine((IDleft+1));
Tabla_Simbolos.insertaValor(ID+"",parser.valor,parser.esId,parser.accion);
GenIntermedio.genCodigo("asig",exp+"",null,ID);
:}
:} mas TERM:e2 {:
String t = GenIntermedio.genTemp();
GenIntermedio.genCodigo("+",e1+"",e2+"",t);
RESULT = t;
:}
String t = GenIntermedio.genTemp();
GenIntermedio.genCodigo("-",e1+"",e2+"",t);
RESULT = t;
:}
| TERM:e2{:
RESULT = e2;
:} ;
String t = GenIntermedio.genTemp();
GenIntermedio.genCodigo("*",e1+"",e2+"",t);
RESULT = t;
:}
String t = GenIntermedio.genTemp();
GenIntermedio.genCodigo("/",e1+"",e2+"",t);
RESULT = t;
:}
| FACT:e1 {:
RESULT = e1;
:};
| id:ID{:
parser.valor=ID;
parser.esId=true;
RESULT = ID;
:}
| VALOR:VA {:
RESULT = VA;
parser.valor=VA+"";
:}
RESULT = e1;
:};
BIBLIOGRAFA
Schildt, H. (2014). Java a beginner's guide. New York: McGraw-
Hill Osborne.