K_ORDENA.cpp



#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <iostream.h>

void error(char , int);

class lectura_de_datos
{
   public:
      char *linea;
      int linea_n;
      lectura_de_datos *sig;

      void muestra (void);		// muestra los datos almacenados
      void lee_archivo (char *);        // lee el archivo *.kar
      void inserta_nodo (char *);       // inserta nodo a la lista
};

class programa
{
   public:
      char *comando;                    		// comando a ejecutar
      programa *sig;                    		// a que nodo apunta
      programa *hacia;                  		// hacia donde va
      programa *de;                     		// de donde viene

      void muestra(void);				// muestra los datos almacenados
      programa *busca(char *);          		// busca comando en lista principal
      char *lee_parte_2(char *);			// lee nombre de funcion de un string
      void crea_arbol(void);				// genera el arbol con los comandos
	 void ambiente(void);				// genera rama de ambiente
	 void ejecucion(void);				// genera rama de ejecucion
	 void funciones(void);				// genera conjunto de funciones
	    void lee_funciones(void);   		// genera el contenido de funciones

      programa *mientras(char *, programa *);		// lee funciones MIENTRAS
};

lectura_de_datos *dato_inicial;		// apuntador al primer nodo
programa *start;                        // apuntador a la raiz del programa

char s[80],fnombre[80];
FILE *fp;


void lectura_de_datos::lee_archivo(char *fnombre)   // fnombre = nombre del ARCHIVO.
{
	 char ch, car[1], linea[80];
	 lectura_de_datos info;
	 int contador = 1;

	 if ((fp = fopen(fnombre,"rt")) == NULL)
	   {  printf("No se puede abrir el archivo"); return; }
	 gotoxy(5,24); printf("Cargando el archivo %s\n",fnombre);

	 ch = fgetc(fp);
	 while (ch != EOF)
	 {
	    linea[0] = '\0';
	    while (ch == ' ' || ch == '\t' )	// quita espacios iniciales
	       ch = fgetc(fp);
	    while (ch != '\n')
	       {
		  car[0] = ch; car[1] = '\0';
		  strcat(linea, car);
		  ch = fgetc(fp);
	       }
	    if (strlen(linea) > 0)
	    {
	       info.inserta_nodo (linea);
	       contador++;
	    }
	    ch = fgetc(fp);
	 }
}

void lectura_de_datos::inserta_nodo (char linea[80])
{
   lectura_de_datos info, *act = NULL, *ant = NULL, *nodo_nuevo = NULL;

   int contador = 1;

   if (!(nodo_nuevo = new lectura_de_datos))
	 { error('m',1); return; };
   if (!dato_inicial)			// es la primera linea
   {
      nodo_nuevo->linea = strdup(linea);
      nodo_nuevo->linea_n = contador;
      nodo_nuevo->sig = NULL;
      dato_inicial = nodo_nuevo;
   }
   else					// ya existe por lo menos una linea
   {
      act = dato_inicial;
      while (act)			// colocarse al final de la lista
	 { ant = act; act = act->sig; contador++; }
      nodo_nuevo->linea = strdup(linea);
      nodo_nuevo->linea_n = contador;
      nodo_nuevo->sig = NULL;
      ant->sig = nodo_nuevo;
   }
}

void error(char letrero, int control)
{
   gotoxy(30,18);
   switch (letrero)
   {
      case 'm':
	 cout << "No hay memoria suficiente.." << "control= " << control;
	 break;
      default:
	cout << "error desconocido";
   }
   getch();
}

void programa::crea_arbol(void)
{
   programa prog;

   prog.ambiente();
   prog.ejecucion(); dato_inicial = dato_inicial->sig;
   prog.funciones();
   prog.lee_funciones();
}

void programa::lee_funciones(void)
{
   programa *p_ant = NULL, *p_nuevo = NULL, *raiz = NULL, prog;
   char cad_aux[11], num[3];
   int repite = 0;

   while (dato_inicial)
   {
      if (strncmp(dato_inicial->linea, "DEFINE_NUEVA_INSTRUCCION", 24) == 0 )
      {
	 raiz = busca ( lee_parte_2 ( dato_inicial->linea ) );	// se coloca al inicio de la funcion
	 p_ant = raiz;
	 dato_inicial = dato_inicial->sig;			// borra DEFINE_NUEVA_INSTRUCCION
	 while (strncmp(dato_inicial->linea, "DEFINE_NUEVA_INSTRUCCION", 24) != 0 )
	 {
	    if (strncmp(dato_inicial->linea, "INICIO", 6) == 0 )
	       { dato_inicial = dato_inicial->sig; continue; }
	    if (strncmp(dato_inicial->linea, "FIN", 3) == 0 )
	       { dato_inicial = dato_inicial->sig; continue; }
	    if (strncmp(dato_inicial->linea, "MIENTRAS", 8) == 0 )
	    {
	       itoa(dato_inicial->linea_n, num, 10);
	       strncpy(cad_aux, dato_inicial->linea, 8);
	       cad_aux[8] = '\0';
	       strcat(cad_aux, num);

	       if (!(p_nuevo = new programa))
		  { error('m',2); return; };
	       p_nuevo->comando = strdup( cad_aux );
	       p_nuevo->sig   = NULL;
	       p_nuevo->hacia = NULL;
	       p_nuevo->de    = NULL;
	       if (!raiz->hacia)
	       {
		  p_ant = p_nuevo;
		  raiz->hacia = p_nuevo;		// liga la funcion con su contenido
	       }
	       else
	       {
		  p_ant->sig = p_nuevo;
		  p_ant = p_nuevo;
	       }
	       p_nuevo->hacia = prog.mientras( cad_aux, p_nuevo);
	       continue;
	    }
	    if ( strncmp(dato_inicial->linea, "REPITE", 6) == 0 )
	    {
	       repite = atoi(lee_parte_2 ( dato_inicial->linea ));
	       // itoa(dato_inicial->linea_n, num, 10);   PARA FUTURA AMPLIACION
	       // cad_aux = strdup( dato_inicial->linea );
	       // strcat(cad_aux, num);                   CON MIENTRAS, SI, ...
	       dato_inicial = dato_inicial->sig;
	       while (repite > 0)
	       {
		  if (!(p_nuevo = new programa))
		     { error('m',3); return; };
		  p_nuevo->comando = strdup( dato_inicial->linea );
		  p_nuevo->sig   = NULL;
		  p_nuevo->hacia = NULL;
		  p_nuevo->de    = NULL;
		  if (!raiz->hacia)
		  {
		     p_ant = p_nuevo;
		     raiz->hacia = p_nuevo;		// liga la funcion con su contenido
		  }
		  else
		  {
		     p_ant->sig = p_nuevo;
		     p_ant = p_nuevo;
		  }
		  // p_nuevo->hacia = prog.mientras(cad_aux, p_nuevo); PARA AMPLIACION
		  repite--;
	       }
	       dato_inicial = dato_inicial->sig;
	       continue;
	    }
	    if ( strncmp(dato_inicial->linea, "SI", 2) == 0 )
	    {

	       dato_inicial = dato_inicial->sig;
	       continue;
	    }
	    // ===================== Es una instruccion =================
	    if (!(p_nuevo = new programa))
		{ error('m',4); return; };
	    p_nuevo->comando = strdup( dato_inicial->linea );
	    p_nuevo->sig   = NULL;
	    p_nuevo->hacia = NULL;
	    p_nuevo->de    = NULL;

	    if (!raiz->hacia)
	    {
		p_ant = p_nuevo;
		raiz->hacia = p_nuevo;		// liga la funcion con su contenido
	    }
	    else
	    {
		p_ant->sig = p_nuevo;
		p_ant = p_nuevo;
	    }
	    dato_inicial = dato_inicial->sig;
	 }
      }
      //dato_inicial = dato_inicial->sig;
   }
}

programa *programa::mientras(char *mientras, programa *viene_de)
{
   programa *p_nuevo = NULL, *pri_rama = NULL;
   programa *raiz = NULL, *p_act = start;
   // int contador_mientras = 0;		FUTURA AMPLIACION

   while (p_act) { raiz = p_act; p_act = p_act->sig; }		// hasta estar al final
   if (!(p_nuevo = new programa))
      { error('m',5); return NULL; };

   p_nuevo->comando = strdup( mientras );	// nombre de instruccion
   p_nuevo->sig   = NULL;
   p_nuevo->hacia = NULL;
   p_nuevo->de    = viene_de;
   raiz->sig      = p_nuevo;		// enlaza con el siguiente
   raiz           = p_nuevo;



   if (!(p_nuevo = new programa))
      { error('m',6); return NULL; };

   p_nuevo->comando = strdup( lee_parte_2( dato_inicial->linea ) );	// condicion
   p_nuevo->sig   = NULL;
   p_nuevo->hacia = NULL;
   p_nuevo->de    = NULL;
   raiz->hacia    = p_nuevo;		// enlaza con su contenido
   pri_rama       = p_nuevo;		// inicio de la rama



   dato_inicial = dato_inicial->sig;		// cuerpo del mientras
   while ( strncmp(dato_inicial->linea, "FIN", 3)    != 0 &&
	   strncmp(dato_inicial->linea, "DEFINE", 6) != 0
	 )
   {
      if (!(p_nuevo = new programa))
      { error('m',7); return NULL; };

      p_nuevo->comando = strdup( dato_inicial->linea );			// comando
      p_nuevo->sig   = NULL;
      p_nuevo->hacia = NULL;
      p_nuevo->de    = NULL;

      if (!pri_rama->sig)
	 { p_act = p_nuevo; pri_rama->sig  = p_nuevo; }
      else
	 { p_act->sig = p_nuevo; p_act = p_nuevo; }
      dato_inicial = dato_inicial->sig;
   }
   p_act->sig = pri_rama;		// reinicia a la condicion
   return raiz;
}

programa *programa::busca(char *cadena)
{
   programa *p_act = start;

   while (p_act)
   {
      if ( strncmp( cadena, p_act->comando, strlen(cadena) ) == 0)
	 return p_act;
      p_act = p_act->sig;
   }
   return NULL;
}

   //             <====================>
   // <=========== LECTURA DE FUNCIONES =================>
   //             <====================>
void programa::funciones(void)
{
   programa *p_nuevo = NULL, *raiz_rama  = start, *raiz = NULL;
   lectura_de_datos *d_act = dato_inicial;

   while (raiz_rama)			    // colocarse al final de la lista
      { raiz  = raiz_rama; raiz_rama = raiz_rama->sig; }

   while (d_act)
   {
      if (strncmp(d_act->linea, "DEFINE_NUEVA_INSTRUCCION", 24) == 0 )
      {
	 if (!(p_nuevo = new programa))
	   { error('m',8); return; };

	 p_nuevo->comando = strdup(lee_parte_2(d_act->linea));	// nombre de instruccion
	 p_nuevo->sig   = NULL;
	 p_nuevo->hacia = NULL;
	 p_nuevo->de    = NULL;
	 raiz->sig      = p_nuevo;		// enlaza con lista de funciones
	 raiz           = p_nuevo;		// recorre al nuevo nodo
      }
      d_act = d_act->sig;
   }
}

   //               <====================>
   // <===========  LECTURA DE EJECUCION  =================>
   //               <====================>
void programa::ejecucion(void)
{
   programa prog, *pri_rama = NULL, *p_ant = NULL;
   programa *p_nuevo, *raiz_rama  = start;
   lectura_de_datos *d_ant = NULL, *d_act = dato_inicial;

   if (!(p_nuevo = new programa))		// reserva memoria
      { error('m',9); return; };
   while (strncmp(d_act->linea, "INICIO_DE_EJECUCION",19) !=0 )
      { d_ant = d_act; d_act = d_act->sig; }
   p_nuevo->comando = strdup(d_act->linea);
   p_nuevo->sig   = NULL;
   p_nuevo->hacia = NULL;
   p_nuevo->de    = NULL;
   raiz_rama->sig = p_nuevo;
   raiz_rama      = p_nuevo;

   d_ant->sig = d_act->sig;			// elimina nodo

   d_act    = d_act->sig;
   p_ant    = NULL;
   pri_rama = NULL;
   while (strncmp(d_act->linea, "FIN_DE_EJECUCION",16) !=0 )
   {
      if (!(p_nuevo = new programa))		// reserva memoria
	 { error('m',10); return; };
      p_nuevo->comando = strdup(d_act->linea);
      p_nuevo->sig   = NULL;
      p_nuevo->hacia = NULL;
      p_nuevo->de    = NULL;
      if (!pri_rama) pri_rama = p_nuevo;
      else
	 p_ant->sig = p_nuevo;
      p_ant = p_nuevo;

      d_ant->sig = d_act->sig;			// elimina nodo
      d_act      = d_act->sig;
   }
   raiz_rama->hacia = pri_rama;		        // enlaza con la segunda rama
   d_ant->sig = d_act->sig;			// elimina nodo
}


   //               <====================>
   // <===========   LECTURA DEL AMBIENTE  =================>
   //               <====================>
void programa::ambiente(void)
{
   programa prog, *pri_rama = NULL, *p_ant = NULL, *p_nuevo, *raiz_rama;

   if (!(p_nuevo = new programa))		// reserva memoria
      { error('m',11); return; };
   start = p_nuevo;			        // inicio de arbol
   raiz_rama = p_nuevo;			// busca el inicio

   while (strncmp(dato_inicial->linea, "INICIO_DE_AMBIENTE", 18) != 0 )
      dato_inicial = dato_inicial->sig;
   p_nuevo->comando = strdup(dato_inicial->linea);
   p_nuevo->sig   = NULL;
   p_nuevo->hacia = NULL;
   p_nuevo->de    = NULL;
   dato_inicial = dato_inicial->sig;
   while (strncmp(dato_inicial->linea, "FIN_DE_AMBIENTE", 15) !=0 )
   {
      if (!(p_nuevo = new programa))		// reserva memoria
	 { error('m',12); return; };
      p_nuevo->comando = strdup(dato_inicial->linea);
      p_nuevo->sig   = NULL;
      p_nuevo->hacia = NULL;
      p_nuevo->de    = NULL;
      if (!pri_rama) pri_rama = p_nuevo;
      else
	 p_ant->sig = p_nuevo;
      p_ant = p_nuevo;
      dato_inicial = dato_inicial->sig;
   }
   raiz_rama->hacia = pri_rama;		    // enlaza con la primera rama
   dato_inicial = dato_inicial->sig;        // desecha el AMBIENTE
}

char *programa::lee_parte_2(char *cadena)
{
   char ch = cadena[0], car[1], *ret = '\0';
   while (ch != ' ')
      { cadena++; ch = cadena[0]; }		// busca espacio
   cadena = cadena++;				// quita espacio
   ch = cadena[0];
   ret[0] = '\0';
   while (ch != ' ')				// busca espacio
   {
      car[0] = ch; car[1] = '\0';
      strcat(ret, car);
      cadena++;
      ch = cadena[0];
   }
   return ret;
}

void main(void)
{
	 char *archivo;
	 lectura_de_datos info;
	 programa prog;

	 dato_inicial = NULL;
	 clrscr();
	 printf("Nombre de archivo: "); gets(archivo);
	 info.lee_archivo (archivo);            // <======= ok
	 prog.crea_arbol();
	 //info.muestra();			// <======= ok
	 prog.muestra();


	 getch();
	 clrscr();
}

void programa::muestra (void)
{
   programa *raiz = start, *act = NULL;
   while (raiz)
   {
      act = raiz->hacia;
      cout << "COMANDO==> " << raiz->comando << "\n";
      while (act)
      {
	 cout << act->comando << "\n";
	 act = act->sig;
      }
      getch();
      raiz = raiz->sig;
   }
}
/*
void lectura_de_datos::muestra (void)
{
   lectura_de_datos *act = dato_inicial;
   while (act)
   {
      cout << act->linea << "<==>(" << act->linea_n << ")\n";
      getch();
      act = act->sig;
   }
}
*/