martes, 6 de junio de 2017

ACTIVIDAD PROGRAMA CON SENTENCIAS

#include<iostream>
#include<conio.h>
using namespace std;
int main (){

int opcion,opcion2,opcion3,i;
int total,cantidad,tot2,pago, cam,num,num2, tol;

do{
do{
cout<<"***Tienda***"<<endl;
cout<<"Menu"<<endl;
cout<<"1.Ver Productos"<<endl;
cout<<"2.Cotizar Productos"<<endl;
cout<<"3.Comprar Productos"<<endl;
cout<<"4.Salir"<<endl;
cout<<"Escoge una opcion: "<<endl;
cin>>opcion;

if(opcion==4){
opcion2=4;
}
switch(opcion){
case 1: {
cout<<"dame un valor que deseas contar"<<endl;
cin>>num;
cout<<"de cuanto deseas que sea el salto"<<endl;
     cin>>num2;
for(i=0;i<=num;i=i+num2)

cout<<i<<endl;



do{
cout<<"*** Elige a el departamento *** "<<endl;
cout<<"1.- Electronica "<<endl;
cout<<"2.- Muebles "<<endl;
cout<<"3.- Regresar al menu "<<endl;
cin>>opcion2;
if(opcion2==3){
opcion3=6;
}
switch(opcion2){
case 1:{
cout<<"*** Electronica ***"<<endl;
cout<<"Smartphone $6,500"<<endl;
cout<<"Pantalla $5,000"<<endl;
cout<<"Dvd $1,500"<<endl;
cout<<"Consola Xbox One $7,600"<<endl;
cout<<"Presione 1 para regresar"<<endl;
cin>>opcion3;
break;
}
case 2:{
cout<<"*** Muebles ***"<<endl;
   cout<<"Sala $9,000 "<<endl;
   cout<<" Comedor $3,500 "<<endl;
   cout<<"Cocina $8,000"<<endl;
   cout<<"Cama Matrimonial $6,600"<<endl;
cout<<"Presione 1 para regresar"<<endl;
cin>>opcion3;
break;
}
}
}while(opcion3<6);
break;
}

case 2:{
do{
cout<<"*** Elige a el departamento *** "<<endl;
cout<<"1.- Electronica "<<endl;
cout<<"2.- Muebles "<<endl;
cout<<"3.- Regresar al menu "<<endl;
cin>>opcion2;
if(opcion2==3){
opcion3=6;
}
switch(opcion2){
case 1:{
cout<<"***Cotizacion del departamento de Electronica***"<<endl;
cout<<"Presiona el numero del producto que deseas cotizar: "<<endl;
cout<<"1.- Smartphone $6,500"<<endl;
cout<<"2.- Pantalla $5,000"<<endl;
cout<<"3.- Dvd $1,500 "<<endl;
cout<<"4.- Consola Xbox One $7,600"<<endl;
cout<<"Presione 1 para regresar"<<endl;
cin>>opcion3;
if(opcion3==1){
cout<<"¿Cuantos Smartphone deseas? "<<endl;
cin>>cantidad;
total=cantidad*6500;
cout<<"Tu cantidad a pagar seria de: "<<total<<endl;
}else{
if(opcion3==2){
cout<<"¿Cuantas pantallas deseas? "<<endl;
cin>>cantidad;
total=cantidad*5000;
cout<<"Tu cantidad a pagar seria de: "<<total<<endl;
}else{
if(opcion3==3){
cout<<"¿Cuantos Dvd deseas? "<<endl;
cin>>cantidad;
total=cantidad*1500;
cout<<"Tu cantidad a pagar seria de: "<<total<<endl;
}else{
if(opcion3==4){
cout<<"¿Cuantos Xbox One deseas? "<<endl;
cin>>cantidad;
total=cantidad*7600;
cout<<"Tu cantidad a pagar seria de: "<<total<<endl;
}
}
}
}
break;
}

case 2: {
cout<<"***Cotizacion del departamento de Muebles***"<<endl;
cout<<"Presiona el numero del producto que deseas cotizar: "<<endl;
   cout<<"1.- Sala $9,000"<<endl;
   cout<<"2.- _Comedor $3,500"<<endl;
   cout<<"3.- Cocina $8,000"<<endl;
   cout<<"4.- Cama matrimonial $6,000"<<endl;
cout<<"Presione 1 para regresar"<<endl;
cin>>opcion3;
if(opcion3==1){
cout<<"¿Cuantas salas deseas? "<<endl;
cin>>cantidad;
total=cantidad*9000;
cout<<"Tu cantidad a pagar seria de: "<<total<<endl;
}else{
if(opcion3==2){
cout<<"¿Cuantos comedores deseas? "<<endl;
cin>>cantidad;
total=cantidad*3500;
cout<<"Tu cantidad a pagar seria de: "<<total<<endl;
}else{
if(opcion3==3){
cout<<"¿Cuantas cocinas deseas? "<<endl;
cin>>cantidad;
total=cantidad*8000;
cout<<"Tu cantidad a pagar seria de: "<<total<<endl;
}else{
if(opcion3==4){
cout<<"¿Cuantas camas matrimoniales deseas? "<<endl;
cin>>cantidad;
total=cantidad*6000;
cout<<"Tu cantidad a pagar seria de: "<<total<<endl;
}
}
}
}
break;
}

}
}while(opcion3<6);
break;
}


case 3:{

do{
cout<<"*** Elige a el departamento *** "<<endl;
cout<<"1.- Electronica "<<endl;
cout<<"2.- Muebles "<<endl;
cout<<"3.- Regresar al menu "<<endl;
cin>>opcion2;
if(opcion2==3){
opcion3=6;
}
switch(opcion2){
case 1:{
cout<<"***Realizar la compra del departamento de Electronica***"<<endl;

cout<<"1.- Smartphone $6,500"<<endl;
cout<<"2.- Pantalla $5,000"<<endl;
cout<<"3.- Dvd $1,500 "<<endl;
cout<<"4.- Consola Xbox One $7,600"<<endl;
cout<<"Elige el producto "<<endl;
cout<<"Presione 1 para regresar"<<endl;
cin>>opcion3;
if(opcion3==1){
cout<<"¿Cuantos Smartphone deseas adquirir? "<<endl;
cin>>cantidad;
total=cantidad*6500;
cout<<"Tu cantidad a pagar es de: "<<total<<endl;
cout<<"Introduce tu pago "<<endl;
cin>>pago;
   tot2=pago-total;
   if (tot2==total){
   cout<<"Gracias por tu compra"<<endl;
   }
   if (tot2>total){
   cam=tot2-total;
cout<<"Tu cambio es de: "<<cam<<endl;
}
   if (tot2<total){
   cam=total-tot2;
   cout<<"Falta por pagar: "<<cam<<endl;
   }

}else{
if(opcion3==2){
cout<<"¿Cuantas pantallas deseas? "<<endl;
cin>>cantidad;
total=cantidad*5000;
cout<<"Tu cantidad a pagar es de: "<<total<<endl;
cout<<"Introduce tu pago "<<endl;
cin>>pago;
   tot2=pago-total;
   if (tot2==total){
   cout<<"Gracias por tu compra"<<endl;
   }
   if (tot2>total){
   cam=tot2-total;
cout<<"Tu cambio es de: "<<cam<<endl;
}
   if (tot2<total){
   cam=total-tot2;
   cout<<"Falta por pagar: "<<cam<<endl;
   }
}else{
if(opcion3==3){
cout<<"¿Cuantos Dvd deseas ? "<<endl;
cin>>cantidad;
total=cantidad*1500;
cout<<"Tu cantidad a pagar es de: "<<total<<endl;
cout<<"Introduce tu pago "<<endl;
cin>>pago;
   tot2=pago-total;
   if (tot2==total){
   cout<<"Gracias por tu compra"<<endl;
   }
   if (tot2>total){
   cam=tot2-total;
cout<<"Tu cambio es de: "<<cam<<endl;
}
   if (tot2<total){
   cam=total-tot2;
   cout<<"Falta por pagar: "<<cam<<endl;
   }
}else{
if(opcion3==4){
cout<<"¿ Cuantos Xbox One deseas? "<<endl;
cin>>cantidad;
total=cantidad*7600;
cout<<"Tu cantidad a pagar es de: "<<total<<endl;
cout<<"Introduce tu pago "<<endl;
cin>>pago;
   tot2=pago-total;
   if (tot2==total){
   cout<<"Gracias por tu compra"<<endl;
   }
   if (tot2>total){
   cam=tot2-total;
cout<<"Tu cambio es de: "<<cam<<endl;
}
   if (tot2<total){
   cam=total-tot2;
   cout<<"Falta por pagar: "<<cam<<endl;
   }
}
}
}
}
break;
}

case 2: {
cout<<"***Realizar compra del departamento Muebles ***"<<endl;
cout<<"1.- Sala $9,000"<<endl;
   cout<<"2.- _Comedor $3,500"<<endl;
   cout<<"3.- Cocina $8,000"<<endl;
   cout<<"4.- Cama matrimonial $6,000"<<endl;
   cout<<"Elige un producto"<<endl;
cout<<"Presione 1 para regresar"<<endl;
cin>>opcion3;
if(opcion3==1){
cout<<"¿Cuantas salas deseas? "<<endl;
cin>>cantidad;
total=cantidad*9000;
cout<<"Tu cantidad a pagar es de: "<<total<<endl;
cout<<"Introduce tu pago "<<endl;
cin>>pago;
   tot2=pago-total;
   if (tot2==total){
   cout<<"Gracias por tu compra"<<endl;
   }
   if (tot2>total){
   cam=tot2-total;
cout<<"Tu cambio es de: "<<cam<<endl;
}
   if (tot2<total){
   cam=total-tot2;
   cout<<"Falta por pagar: "<<cam<<endl;
   }
}else{
if(opcion3==2){
cout<<"¿Cuantos comedores deseas? "<<endl;
cin>>cantidad;
total=cantidad*3500;
cout<<"Tu cantidad a pagar es de: "<<total<<endl;
cout<<"Introduce tu pago "<<endl;
cin>>pago;
   tot2=pago-total;
   if (tot2==total){
   cout<<"Gracias por tu compra"<<endl;
   }
   if (tot2>total){
   cam=tot2-total;
cout<<"Tu cambio es de: "<<cam<<endl;
}
   if (tot2<total){
   cam=total-tot2;
   cout<<"Falta por pagar: "<<cam<<endl;
   }
}else{
if(opcion3==3){
cout<<"¿Cuantas cocinas deseas? "<<endl;
cin>>cantidad;
total=cantidad*8000;
cout<<"Tu cantidad a pagar es de: "<<total<<endl;
cout<<"Introduce tu pago "<<endl;
cin>>pago;
   tot2=pago-total;
   if (tot2==total){
   cout<<"Gracias por tu compra"<<endl;
   }
   if (tot2>total){
   cam=tot2-total;
cout<<"Tu cambio es de: "<<cam<<endl;
}
   if (tot2<total){
   cam=total-tot2;
   cout<<"Falta por pagar: "<<cam<<endl;
   }
}else{
if(opcion3==4){
cout<<"¿Cuantas camas matrimoniales deseas? "<<endl;
cin>>cantidad;
total=cantidad*6000;
cout<<"Tu cantidad a pagar es de: "<<total<<endl;
cout<<"Introduce tu pago "<<endl;
cin>>pago;
   tot2=pago-total;
   if (tot2==total){
   cout<<"Gracias por tu compra"<<endl;
   }
   if (tot2>total){
   cam=tot2-total;
cout<<"Tu cambio es de: "<<cam<<endl;
}
   if (tot2<total){
   cam=total-tot2;
   cout<<"Falta por pagar: "<<cam<<endl;
   }
}
}
}
}
break;
}
}
}while(opcion3<6);
break;

}

}
}while(opcion2<4);
}while(opcion!=4);
getch();
}

lunes, 8 de mayo de 2017

Analisis semantico y generacion de codigo intermedio


public class Principal {

 /**
  * @param args
  */
 public static void main(String[] args) {
  

 System.out.println("-------------------<< Clase Padre Vehiculo >>-----------------------");
 Vehiculo miVehiculo = new Vehiculo();
 miVehiculo.nombreVehiculo="El Gran Transportador";
 System.out.println("usando miVehiculo, nombreVehiculo : "+miVehiculo.nombreVehiculo);
 System.out.println("usando miVehiculo llama a: "+miVehiculo.transportar());
 System.out.println("--------------------------------------------------------------------");
 System.out.println();
 
 System.out.println("----------<< SubClase hija Acuatico Extiende de Vehiculo >>---------");
 Acuatico miAcuatico= new Acuatico();
 miAcuatico.nombreVehiculo="El Navegante";
 System.out.println("usando miAcuatico, nombreVehiculo : "+miAcuatico.nombreVehiculo);
 System.out.println("usando miAcuatico llama a : "+miAcuatico.transportar());
 System.out.println("usando miAcuatico llama a : "+miAcuatico.navegar());
 System.out.println("---------------------------------------------------------------------");
 System.out.println();
 
 System.out.println("-----<< SubClases hijas extienden de la Subclase Padre Acuatico>-----");
 Barco miBarco=new Barco();
 miBarco.nombreVehiculo="Titanic";
 System.out.println("usando miBarco, nombreVehiculo : "+miBarco.nombreVehiculo);
 System.out.println("usando miBarco llama a : "+miBarco.transportar());
 System.out.println("usando miBarco llama a : "+miBarco.navegar());
 System.out.println("usando miBarco llama a : "+miBarco.prenderMotor());
 System.out.println();
 
 Velero miVelero=new Velero();
 miVelero.nombreVehiculo="Tormenta";
 System.out.println("usando miVelero, nombreVehiculo : "+miVelero.nombreVehiculo);
 System.out.println("usando miVelero llama a : "+miVelero.transportar());
 System.out.println("usando miVelero llama a : "+miVelero.navegar());
 System.out.println("usando miVelero llama a : "+miVelero.izarVelas());
 System.out.println("---------------------------------------------------------------------");
 
 System.out.println("----------<< SubClase hija Aereo Extiende de Vehiculo >>---------");
 Aereo miAereo= new Aereo();
 miAereo.nombreVehiculo="El Volador";
 System.out.println("usando miAereo, nombreVehiculo : "+miAereo.nombreVehiculo);
 System.out.println("usando miAereo llama a : "+miAereo.transportar());
 System.out.println("usando miAereo llama a : "+miAereo.volar());
 System.out.println("---------------------------------------------------------------------");
 System.out.println();
 
 System.out.println("-----<< SubClases hijas extienden de la Subclase Padre Aereo >-----");
 Avion miAvion=new Avion();
 miAvion.nombreVehiculo="El Condor";
 System.out.println("usando miAvion, nombreVehiculo : "+miAvion.nombreVehiculo);
 System.out.println("usando miAvion llama a : "+miAvion.transportar());
 System.out.println("usando miAvion llama a : "+miAvion.volar());
 System.out.println("usando miAvion llama a : "+miAvion.bajarTrenDeAterrizaje());
 System.out.println();
 
 Helicoptero miHelicoptero=new Helicoptero();
 miHelicoptero.nombreVehiculo="El lobo del Aire";
 System.out.println("usando miHelicoptero, nombreVehiculo : "+miHelicoptero.nombreVehiculo);
 System.out.println("usando miHelicoptero llama a : "+miHelicoptero.transportar());
 System.out.println("usando miHelicoptero llama a : "+miHelicoptero.volar());
 System.out.println("usando miHelicoptero llama a : "+miHelicoptero.encenderHelices());
 System.out.println("---------------------------------------------------------------------");
 System.out.println();
 
 System.out.println("--<< Propiedad de la clase Vehiculo usada por todas las clases Hijas >--");
 System.out.println("nombre Vehiculo :"+miVehiculo.nombreVehiculo);
 System.out.println("nombre Acuatico :"+miAcuatico.nombreVehiculo);
 System.out.println("nombre Aereo :"+miAereo.nombreVehiculo);
 System.out.println("nombre Barco :"+miBarco.nombreVehiculo);
 System.out.println("nombre Velero :"+miVelero.nombreVehiculo);
 System.out.println("nombre Avion :"+miAvion.nombreVehiculo);
 System.out.println("nombre Helicoptero :"+miHelicoptero.nombreVehiculo);
 System.out.println("---------------------------------------------------------------------");
 
 }
}


Vehiculo.
Clase Padre.
/**
 * @author HENAO
 *
 */
public class Vehiculo {
 
 public int modeloVehiculo;
 
 public String nombreVehiculo="";
 
 public String transportar(){
  return "Metodo transportar de clase Vehiculo";
 }
}
Acuatico.
SubClase extiende de Vehiculo.
public class Acuatico extends Vehiculo{
 
 public String nombreAcuatico="";
 
 public String navegar(){
  return "Método navegar de clase Acuatico";
 }

}
Aereo.
SubClase extiende de Vehiculo.
public class Aereo extends Vehiculo {
 
 public String nombreAereo="";
 
 public String volar(){
  return "Método volar desde clase Aereo";
 }
}
Barco.
SubClase extiende de Acuatico.
public class Barco extends Acuatico {
 
 public String prenderMotor(){
   return "Método prenderMotor en clase Barco";
 }
}
Velero.
SubClase extiende de Acuatico.
public class Velero extends Barco{
 
 public String izarVelas(){
  return "Método izarVelas en clase Velero";
 }
}
Clase Avion.  SubClase extiende de Aereo.
public class Avion extends Aereo{
 
 public String bajarTrenDeAterrizaje(){
  return "Método bajarTrenDeAterrizaje en clase Avion";
 }
}
Clase Helicoptero. SubClase extiende de Aereo.
public class Helicoptero extends Aereo{
 
 public String encenderHelices(){
  return "Método encenderHelices en clase Helicoptero";
 }
}

Diferencia entre atributos heredados y atributos sintetizados


Atributos Sintetizados

  • Los atributos sintetizados se utilizan ampliamente.
  • Si una definición dirigida por sintaxis tiene únicamente atributos sintetizados se dice que es S-atribuida.
  • El árbol de análisis sintáctico de una gramática S-atribuida puede decorarse mediante un recorrido en post orden.

Atributos Heredados

  • Sirven para expresar la dependencia que hay entre una construcción del lenguaje de programación y su contexto.
  • Siempre es posible reescribir una definición dirigida por sintaxis para que sea S-atribuida.
  • En ocasiones es más natural utilizar atributos heredados


martes, 4 de abril de 2017

Generacion de codigo

GENERACION DE CODIGO
En el modelo de análisis y síntesis de un compilador, la etapa inicial traduce un programa fuente a una representación intermedia a partir de la cual la etapa final genera el código 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 de utilizar una forma intermedia independiente de la máquina son:
1. Se facilita la re destinación; se puede crear un compilador para una máquina distinta uniendo una etapa final para la nueva máquina a una etapa inicial ya existente.
2. Se puede aplicar a la representación intermedia un optimizador de código independiente de la máquina.

El código intermedio que vamos a usar, posee cuatro apartados:
• Operando 1º
• Operando 2º
• Operador
• Resultado
y se denomina código de 3 direcciones, de tercetos, o máximo 3 operandos.

Hay algunas instrucciones que carecen de algunos de estos apartados; los tercetos que podemos usar son:
• Asignación binaria: x := y op z, donde op es una operación binaria aritmética o lógica.
• Asignación unaria: x := op, donde op es una operación unaria. Las operaciones unarias principales incluyen el menos unario, la negación lógica, los operadores de desplazamiento y operadores de conversión de tipos.
• Asignación simple o copia: x := y, donde el valor de y se asigna a x.
• Salto incondicional: goto etiqueta.
• Saltos condicionales: if x oprelacional y goto etiqueta

a = 3 + b + 5 + c
Hasta ahora, para generar el código de tercetos no hemos tenido que tener en cuenta los valores de a, b, y c. Por lo tanto no nos ha hecho falta ninguna tabla de símbolos para generar el código de terceto. Según el problema que tengamos planteado hay que ver si hace falta o no una tabla de símbolos. En el ejemplo anterior no hace falta una tabla de símbolos, porque no hay chequeo de tipos. Pero si tenemos un problema en el que exista una zona de declaración y una zona de definición

Generación de código en Sentencias de control
En el caso de las expresiones, nos basábamos en las variables temporales para generar código. Ahora el problema son los cambios de flujos
IF - THEN- ELSE
CASE
WHILE
REPEAT
Vamos a trabajar con cambios de flujos mediante condiciones:
WHILE _ Mientras se cumple la condición
REPEAT _ Hasta que se cumpla la condición

Condición compuesta: Si se enlazan condiciones mediante operadores lógicos AND u
OR emplearemos la técnica del cortocircuito, de manera que si enlazamos cond1 y cond2 con un AND, (cond1 AND cond2), pues si cond1 es falso, no evaluaremos cond2, dado que su función será falsa sea cual sea el valor de cond2.
Si el conector es OR, (cond1 OR cond2), la cond2 sólo se evaluará si la cond1 es falsa, pues en caso contrario, su disyunción será verdad para cualquier valor de cond2.

Sentencias que nos permite nuestro lenguaje
Ahora se trata de utilizar estas condiciones y sus etiquetas asociadas, para generar el código de sentencias que implican condiciones, como son IF, WHILE y REPEAT.
Sentencia IF-THEN-ELSE
El caso del IF es el caso más simple. Aquí basta, con indicar que la etiqueta de verdad de la condición está asociada al código a continuación del THEN, y la etiqueta de falso se asocia al código que puede haber tras el ELSE. En cualquier caso, una vez acabadas las sentencias del THEN se debe producir un salto al final del IF, porque no queremos que se ejecuten también las sentencias del ELSE. Por tanto, tras la sentencias del THEN, creamos una nueva etiqueta a la cual produciremos un salto, y colocamos el destino de tal etiqueta al final del código del IF

Sentencia WHILE
El caso de WHILE y REPEAT es muy similar. En ambos creamos una etiqueta al comienzo del bucle, a la que se saltará para repetir cada iteración.
En el caso del WHILE, a continuación se genera el código de la condición. La etiqueta de verdad se pone justo antes de las sentencias del WHILE, que es lo que se debe ejecutar si la condición es cierta. Al final de las sentencias se pondrá un salto al inicio del bucle, donde de nuevo se comprobará la condición. La etiqueta de falso de la condición, se pondrá al final de todo lo relacionado con el WHILE, o lo que es lo mismo, al principio del código generado para las sentencias que siguen al WHILE.

IF cond THEN sent ELSE sent FIN IF
| WHILE cond DO sent FIN WHILE
Sentencia REPEAT
Como ya se dijo, creamos una etiqueta al comienzo del bucle, a la que se saltará para repetir cada iteración
En el caso del REPEAT, a continuación de la etiqueta de comienzo del bucle colocamos el código de las sentencias, ya que la condición se evalúa al final. Tras las sentencias colocamos el código de la condición. Ahora, debemos hacer coincidir la etiqueta de comienzo del bucle con la etiqueta de falso de la condición,. Como ambos nombres ya están asignados, la solución es colocar la etiqueta de falso, y en ella un goto al comienzo del bucle.
Al final de todo el código asociado al REPEAT pondremos la etiqueta de verdad.
IF cond THEN sent ELSE sent FIN IF
| WHILE cond DO sent FIN WHILE
| REPEAT sent UNTIL cond

Sentencia CASE
La sentencia más compleja de todas es la sentencia CASE, ya que ésta permite un número indeterminado, y potencialmente infinito de condiciones, lo cual obliga a arrastrar una serie de parámetros a medida que se van efectuando reducciones.
El problema es que la sentencia CASE necesita una recursión (no podemos utilizar una única regla de producción). Es necesario una regla de producción para la sentencia CASE diferente.

AST (Abstract Syntax Trees): forma condensada de árboles de análisis, con sólo nodos semánticos y
sin nodos para símbolos terminales (se supone que el programa es sintácticamente correcto).
• Ventajas: unificación de pasos de compilación
– Creación del árbol y la tablade símbolos
– Análisis semántico
– Optimización
– Generación de código objeto
• Desventaja:
– espacio para almacenamiento

DAG (Directed Acyclic Graphs): árboles sintácticos concisos

Ahorran algo de espacio
– Resaltan operaciones duplicadas en el código
– Difíciles de construir
TAC (Three-Address Code): secuencia de instrucciones de la forma:

– operador: aritmético / lógico
– operandos/resultado: constantes, nombres, temporales.
• Se corresponde con instrucciones del tipo:
A := b + c

• Las operaciones más complejas requieren varias instrucciones:
• Este ‘desenrollado’ facilita la optimización y generación de código final.
• Ensamblador general y simplificado para una máquina virtual: incluye etiquetas, instrucciones de flujo de control…
• Incluye referencias explícitas a las direcciones de los resultados intermedios (se les da nombre).
• La utilización de nombres permite la reorganización (hasta cierto punto).
• Algunos compiladores generan este código como código final; se puede interpretar fácilmente (UCSD PCODE, Java).

Notación posfija
• Polaca inversa, código de cero direcciones:
– notación matemática libre de paréntesis
– los operadores aparecen después de los operandos
• Ventajas:
– Código generado conciso.
– No hacen falta temporales.
– Algunas optimizaciones sencillas.
– Mantiene la estructura sintáctica.
• Desventajas:
– Código dependiente de la posición.
– solo efectiva si el ‘target’ es de pila.

Generación de código intermedio
• Consideración fundamental: generación de código correcto.
• no se genera código (hay excepciones).
• se limita a resolver problemas relacionados con almacenamiento de los objetos:
– Espacio requerido
– Lugar en la memoria
– Valor
• hay información explícita e implícita en el fuente.
• ¿Y si se permite mezclar declaraciones de variables y procedimientos?
• ¿Y si necesitas mantener información sobre el tamaño de cada bloque?
• C: este problema no existe.
• Pascal: muchos compiladores lo prohíben.

Expresiones y Asignación
• De los operandos:
– Determinar su localización
– Efectuar conversiones implícitas
• De los operadores:
– Respetar su precedencia
– Respetar su asociatividad
– Respetar orden de evaluación (si definido)
– Determinar interpretación correcta (si sobrecargado)
• Instrucciones generadas
– Acceso a datos
» Variables simples
» Registros
» Vectores
– Manipulación de datos
» Conversiones
» Operaciones
– Flujo de control
» Validación de subrangos
» Operadores complejos
Reutilización de temporales
• Una vez que una variable temporal aparece como operando, deja de utilizarse.
• Al traducir el código intermedio, en lo posible se utilizarán registros (habrá una cantidad limitada); de lo contrario, posiciones de memoria.
• Reducción de temporales requeridas:

Invocación de Procedimientos
• Cuando se evalúan las expresiones correspondientes a los argumentos, éstos van almacenándose en la pila.
• Al crear el BA del procedimiento, debe respetarse el tamaño del bloque actual
• El cambio de nivel es la diferencia entre el nivel actual y el invocado.
• La dirección del procedimiento o función se determina al introducir el símbolo en la tabla.

Utilización de parámetros
1. valor de un parámetro por referencia
2. dirección de un parámetro por referencia
3. valor de un parámetro por valor y otro por referencia
4. parámetro por valor utilizado como argumento a parámetro por referencia
5. parámetro por referencia utilizado como argumento a parámetro por referencia
6. variables utilizadas como parámetros por valor y referencia respectivamente



lunes, 27 de marzo de 2017

Analizador Sintáctico

El análisis sintáctico es un análisis a nivel de sentencias, y es mucho más complejo que el análisis léxico. Su función es tomar el programa fuente en forma de tokens, que recibe del analizador léxico, y determinar la estructura de las sentencias del programa. Este proceso es similar a determinar la estructura de una frase en Castellano, determinando quien es el sujeto, predicado, el verbo y los complementos. 

El análisis sintáctico agrupa a los tokens en clases sintácticas (denominadas no terminales en la definición de la gramática), tales como expresiones, procedimientos, etc. El analizador sintáctico o parser obtiene un árbol sintáctico (u otra estructura equivalente) en la cual las hojas son los tokens, y cualquier nodo que no sea una hoja, representa un tipo de clase sintáctica (operaciones). Por ejemplo el análisis sintáctico de la siguiente expresión

La estructura de la gramática anterior refleja la prioridad de los operadores, así los operadores “+” y “-” tienen la prioridad más baja, mientras que “*” y “/” tienen una prioridad superior. Se evaluaran en primer lugar las constantes, variables y expresiones entre paréntesis. Los árboles sintácticos se construyen con un conjunto de reglas conocidas como gramática, y que definen con total precisión el lenguaje fuente. Al proceso de reconocer la estructura del lenguaje fuente se conoce con el nombre de análisis sintáctico (parsing). Hay distintas clases de analizadores o reconocedores sintácticos, pero en general se clasifican en 2 grandes grupos: A.S. Ascendentes y A.S. Descendentes.

Caracteristicas 

• Lee componentes léxicos (tokens)
• Comprueba que el orden de estos corresponde a la sintaxis predeterminada
 • Genera errores en caso de que el flujo de tokens no responda a la sintaxis
 • Genera árboles de análisis sintáctico
 • Se suele conocer como “Parser”
• El análisis sintáctico desarrolla el esqueleto de toda la fase de análisis
• Utiliza el analizador léxico como una rutina dentro del análisis sintáctico ( getNextToken() )
 • Integra el análisis semántico como un conjunto de rutinas a ejecutar durante la comprobación de la sintaxis.
• Aunque el objetivo teórico es construir un árbol de análisis sintáctico, este raramente se construye como tal, sino que las rutinas semánticas integradas van generando el árbol de sintaxis abstracta.
• El análisis sintáctico se especifica mediante una gramática libre de contexto
• El análisis sintáctico se implementa mediante un autómata de pila

Analizador sintáctico ascendente: Intenta construir un árbol de análisis sintáctico, empezando desde la raíz y descendiendo hacia las hojas. Lo que es lo mismo que intentar obtener una derivación por la izquierda para una cadena de entrada, comenzando desde la raíz y creando los nodos del árbol en orden previo.

 Analizador sintáctico descendente: Intenta construir un árbol de análisis sintáctico, empezando desde las hojas (la cadena) y ascendiendo hacia la raíz. Lo que es lo mismo que intentar obtener una reducción desde una cadena hasta llegar al axioma. El analizador sintáctico tanto ascendente como descendente puede representarse de dos formas: mediante tabla de análisis sintáctico o mediante autómata de pilas.

Elminacion de re cursiva de izquierda

Una gramática es recursiva por la izquierda si tiene un no terminal A tal que existe una derivación A           Aα  para alguna cadena  α. Los métodos de análisis sintáctico descendente no pueden manejar gramáticas  recursivas por la izquierda, así que se necesita una transformación que elimine la recursión por la izquierda.
Recursión por la izquierda inmediata simple  (Eliminación de la recursividad izquierda de las producciones)
En este caso la recursión por la izquierda se presenta solo en las reglas gramaticales
A → A α | β
Donde α y β son cadenas de terminales y no terminales y  β no comienza en A. Esta regla genera todas las cadenas de la forma β, β α, β α α…Todas las cadenas comienzan con una β, seguida por     (0 o mas α). Esta regla gramatical es equivalente a la expresión regular β αⁿ
Para eliminar  la recursión por la izquierda  volvemos a escribir estas reglas gramaticales divididas en dos: una para que primero genere β y otra que genere  las repeticiones de α utilizando recursión por la derecha en vez de recursión por la izquierda:
A → β A´
A´→ α A´|є
Ejemplo Considere de nueva cuenta la regla recursiva izquierda de la gramática de expresión simple:
exp → exp opsuma term | term
La forma de esta regla es  A → A α | β, con A= exp,  α=opsuma term y β=term. Al volverla a escribir para eliminar la recursividad por la izquierda obtenemos que
exp → term exp´