jueves, 14 de enero de 2010

Calculo de Iniciales

<<<<<<<  Programa Para Calculo de Iniciales  >>>>>>>>>


#include "Iniciales.h"

char NoTerminales[ 100 ];
char Terminales[ 100 ];

int main( int argc, char** argv )
{
   CIniciales calcIni;
   fstream Salida;
   char buffIni[ 100 ] = "";
   int i;
   cout<<"     Programa de Calculo de Iniciales"<
   cout<
   cout<<"     Misael Miramotes Flores"<
   cout<
   cout<

         calcIni.SetFname( "Gramatica.txt" );//Nombre del archivo

if( calcIni.CargarGramatica() == NOABRE )
     cout << "error al abrir la gramatica!" << endl;
  
  
   else
    {   char nt[ 100 ], alf[ 100 ], ini[ 100 ];
      
        for( i=0; i <= calcIni.NumProducciones(); i++ ) // cal. los iniciales
         {
           calcIni.ObtenerProduccion( nt, alf, ini, i );
          
           if( !strlen( ini ) ) calcIni.CalcIniciales( i, buffIni );
         }
      
        Salida.open( SALIDA, ios::out );
      
        if( Salida.fail() ) cout << "No se puede guardar el archivo de iniciales" << endl;
      
        else
         {
           for( i=0; i <= calcIni.NumProducciones(); i++ )
            {
              calcIni.ObtenerProduccion( nt, alf, ini, i );
              Salida << nt << " -> " << ini << endl;
 cout<< nt << " -> " << ini << endl;
            }
           cout<
           cout << "Este fue el resultado del calculo de iniciales" << endl;
  cout<
  cout<<"Este resultado tambien se puede encontrar en la misma carpeta en Iniciales.txt"<
  cout<
         }
    }

   if( argc > 1 ) cin.sync(), cin.get();
  
   cout << 0;
  
   return 0;
}

int BuscarTerminal( const char* T )
{
  int i;
 
  for( i=0; Terminales[ i ]; i++ ) if( Terminales[ i ] == T[0] ) return i;
 
  return ERROR_NO_ENCONTRADO;
}

CIniciales::CIniciales()
{
   this-> prod = NULL;
   this-> ultimaProd = -1;
}

CIniciales::~CIniciales()
{
   int i = this-> ultimaProd;
  
   if( this-> prod ) // si es distinto de NULL
    {
      for( ; i >= 0; i--)
       {
          delete[] this-> prod[ i ].Nterminal;
          delete[] this-> prod[ i ].Alfa;
          delete[] this-> prod[ i ].inicial;
       }
    
      delete[] this-> prod;
    }
}
  
inline int CIniciales::NumProducciones() { return this-> ultimaProd; }

inline int CIniciales::SetFname( const char* File )
{ strcpy( this-> archivo, File ); return 0; }

int CIniciales::CargarGramatica()
{
   char buffer[ MAX_BUFF ];
   char Nt[ 20 ], alf[ 100 ];
   char auxNt[ 20 ], auxAlfa[ 100 ], auxIni[ 3 ];
   int i = 0, j = 0, ind;
   fstream fgrama;
  
   fgrama.open( this-> archivo, ios::in );
   if( fgrama.fail() ) return NOABRE;
  
   fgrama.getline( buffer, MAX_BUFF );
  
   while( buffer[ i++ ] != '=' ) ;
  
   i++;
  
   while( buffer[ i ] ) // obtienes no terminales
    {
      if( buffer[ i ] != ' ' ) NoTerminales[ j++ ] = buffer[ i ];
      
      i++;
    }
      
   NoTerminales[ j ] = 0;
  
   fgrama.getline( buffer, MAX_BUFF );
      
   i = 0; j = 0;
  
   while( buffer[ i++ ] != '=' ) ;
  
   i++;
      
   while( buffer[ i ] ) // obtienes terminales
    {
      if( buffer[ i ] != ' ' && buffer[ i ] != ',' ) Terminales[ j++ ] = buffer[ i ];

      i++;
    }
      
   Terminales[ j ] = 0;
  
   while( !fgrama.eof() ) // carga las producciones
    {
       fgrama.getline( buffer, MAX_BUFF );
      
       if( !strlen( buffer ) ) continue;
      
       for( j=0, i=0; buffer[ i ]; i++ ) // obtiene el no terminal
        {
           if( buffer[ i ] == ' ' ) continue;

           if( buffer[ i ] != '-' && buffer[ i+1 ] != '>' )
            {
              Nt[ j++ ] = buffer[ i ];
              continue;
            }
          
           else
            {
              Nt[ j ] = 0;
              i += 2;
              break;
            }
        }
      
       for( j=0; buffer[ i ]; i++ )
        {
           if( buffer[ i ] == ' ' ) continue;
          
           alf[ j++ ] = buffer[ i ];
        }
      
       alf[ j ] = 0;
      
       ind = this-> BuscarProduccion( Nt ); // busca una produccion
      
       if( ind != ERROR_NO_ENCONTRADO )
        {
          this-> ObtenerProduccion( auxNt, auxAlfa, auxIni, ind );
        
          strcat( auxAlfa, "," ); strcat( auxAlfa, alf );
        
          this-> ModificarProduccion( Nt, auxAlfa, "", ind );
        }
      
       else  this-> AgregarProduccion( Nt, alf, "" );
      
    }
  
   fgrama.close();
  
   return 0;
}

int CIniciales::CalcIniciales( int indice, char* lista_ini )
{
   int i, j, tam, ind, k;
   char temp[ 5 ];
  
   tam = strlen( this-> prod[ indice ].Alfa );
   k = strlen( lista_ini );
  
   for( i=0, j=0, k=0; i < tam; i++ )
    {
      temp[ j ] = this-> prod[ indice ].Alfa[ i ];

      if( this-> prod[ indice ].Alfa[ i+1 ] == '\'' )
       {
         temp[ j++ ] = this-> prod[ indice ].Alfa[ i++ ];
       }
    
      temp[ ++j ] = 0;

      ind = BuscarTerminal( temp );
    
      if( ind != ERROR_NO_ENCONTRADO ) // si es terminal, lo agrega como inicial
       {
         lista_ini[ k++ ] = Terminales[ ind ];
         lista_ini[ k++ ] = ',';
         lista_ini[ k ] = 0;
       }
      
      else // si es un no terminal, busca sus iniciales
       {
         ind = this-> BuscarProduccion( temp );
        
         this-> CalcIniciales( ind, lista_ini );
         k = strlen( lista_ini );
       }
    
      for( i++; this-> prod[ indice ].Alfa[ i ]; i++ )
       {
         if( this-> prod[ indice ].Alfa[ i ] == ',' ) break;
       }
      
      j = 0;
    }
  
   if( this-> prod[indice].inicial ) delete[] this-> prod[ indice ].inicial;
  
   if( lista_ini[ k-1 ] == ',' ) lista_ini[ k-1 ] = 0;
  
   this-> prod[ indice ].inicial = new char[ strlen( lista_ini )+1 ];
   strcpy( this-> prod[ indice ].inicial, lista_ini );
  
   return 0;
}

int CIniciales::AgregarProduccion( const char* Nterm, const char* alfa, const char* Inicial )
{
   int i = 0;
   PRODUCCION *temp;
  
   this-> ultimaProd++;
  
   temp = new PRODUCCION[ this-> ultimaProd+1 ];
  
   if( !temp ) return ERROR_DE_ASIGNACION_DE_MEMORIA;
  
   for( ; i < this-> ultimaProd; i++ )
    {
      temp[ i ].Nterminal = this-> prod[ i ].Nterminal;
      temp[ i ].Alfa    = this-> prod[ i ].Alfa;
      temp[ i ].inicial = this-> prod[ i ].inicial;
    }
  
   delete[] this-> prod;
  
   temp[ i ].Nterminal = new char[ strlen( Nterm ) +1 ];
   temp[ i ].Alfa    = new char[ strlen( alfa ) +1 ];
   temp[ i ].inicial = new char[ strlen( Inicial ) +1 ];
  
   if( !temp[ i ].Nterminal || !temp[ i ].Alfa || !temp[ i ].inicial )
     return ERROR_DE_ASIGNACION_DE_MEMORIA;
    
   strcpy( temp[ i ].Nterminal, Nterm );
   strcpy( temp[ i ].Alfa, alfa );
   strcpy( temp[ i ].inicial, Inicial );
  
   this-> prod = temp;
  
   return this-> ultimaProd;
}

int CIniciales::BuscarProduccion( const char* Nterm )
{
   int i = 0;
  
   while( i <= this-> ultimaProd )
    {
      if( !strcmp( this-> prod[ i ].Nterminal, Nterm ) ) return i;
      i++;
    }
      
   return ERROR_NO_ENCONTRADO;
}

int CIniciales::ModificarProduccion( const char* Nterm, const char* alfa, const char* Inicial, int indice )
{
   if( indice < 0 || indice > this-> ultimaProd ) return ERROR_FUERA_DE_RANGO;
  
   delete[] this-> prod[ indice ].Nterminal;
   delete[] this-> prod[ indice ].Alfa;
   delete[] this-> prod[ indice ].inicial;
  
   this-> prod[ indice ].Nterminal = new char[ strlen( Nterm ) +1 ];
   this-> prod[ indice ].Alfa    = new char[ strlen( alfa ) +1 ];
   this-> prod[ indice ].inicial = new char[ strlen( Inicial ) +1 ];
  
   if( !prod[ indice ].Nterminal || !prod[ indice ].Alfa || !prod[ indice ].inicial )
      return ERROR_DE_ASIGNACION_DE_MEMORIA;
    
   strcpy( this-> prod[ indice ].Nterminal, Nterm );
   strcpy( this-> prod[ indice ].Alfa, alfa );
   strcpy( this-> prod[ indice ].inicial, Inicial );
  
   return indice;
}

int CIniciales::ObtenerProduccion( char* Nterm, char* alfa, char* Inicial, int indice )
{
   if( indice < 0 || indice > this-> ultimaProd ) return ERROR_FUERA_DE_RANGO;
  
   strcpy( Nterm, this-> prod[ indice ].Nterminal );
   strcpy( alfa, this-> prod[ indice ].Alfa );
   strcpy( Inicial, this-> prod[ indice ].inicial );
  
   return indice;
}


<<<<<<   Programa En .h   >>>>>>>

#ifndef INICIALES_H
#define INICIALES_H

#include
#include
#include

using namespace std;

#ifndef MAX_PATH
#define MAX_PATH 256
#endif

#define MAX_BUFF 256

#define SALIDA "iniciales.txt"

#define ERROR_DE_ASIGNACION_DE_MEMORIA -1
#define NOABRE   -2
#define ERROR_NO_ENCONTRADO   -3
#define ERROR_FUERA_DE_RANGO           -4


typedef struct _PRODUCCION
{
   char *Nterminal;
   char *Alfa;
   char *inicial;
   
} PRODUCCION;

 // clase que se utilizan para el de archivos
class CIniciales
{
   private:
    PRODUCCION *prod;
    int  ultimaProd;
    char archivo[ MAX_PATH ];

   public:
    CIniciales();
    ~CIniciales();
    
    int SetFname( const char* File );
    int CalcIniciales( int indice, char* lista_ini );
    int NumProducciones();
    
    int CargarGramatica();
    int AgregarProduccion( const char* Nterm, const char* alfa, const char* Inicial );
    int BuscarProduccion( const char* Nterm );
    int ModificarProduccion( const char* Nterm, const char* alfa, const char* Inicial, int indice );
    int ObtenerProduccion( char* Nterm, char* alfa, char* Inicial, int indice );
};

int BuscarTerminal( const char* T );

#endif


<<<<<<<<<<<<<<<<<<<<<<<<<<<<<




0 comentarios:

Publicar un comentario

Suscribirse a Enviar comentarios [Atom]

<< Inicio