NT = E,E',T,T',F
T = +,*,(,),#,i
E -> TE'
E' -> +TE'
E'-> #
T -> FT'
T' -> *FT'
T' -> #
F -> (E)
F -> i
Codigo de Calculo de Iniciales
Archivo CPP
#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<<"**********Calculo de Iniciales**********"<
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++ ) // calculo de los iniciales
{
calcIni.ObtenerProduccion( nt, alf, ini, i );
if( !strlen( ini ) ) calcIni.CalcIniciales( i, buffIni );
}
Salida.open( SALIDA, ios::out );
if( Salida.fail() ) cout << "ERROR! 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 << "Simbolos Iniciales Calculados" << endl;
}
}
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 ERR_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 ] ) // obtener 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 ] ) // se obtienen terminales
{
if( buffer[ i ] != ' ' && buffer[ i ] != ',' ) Terminales[ j++ ] = buffer[ i ];
i++;
}
Terminales[ j ] = 0;
while( !fgrama.eof() ) // 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++ ) // obtiene el alfa
{
if( buffer[ i ] == ' ' ) continue;
alf[ j++ ] = buffer[ i ];
}
alf[ j ] = 0;
ind = this-> BuscarProduccion( Nt ); // busca una produccion
if( ind != ERR_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 != ERR_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 ERR_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 ERR_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 ERR_NO_ENCONTRADO;
}
int CIniciales::ModificarProduccion( const char* Nterm, const char* alfa, const char* Inicial, int indice )
{
if( indice < 0 || indice > this-> ultimaProd ) return ERR_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 ERR_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 ERR_FUERA_DE_RANGO;
strcpy( Nterm, this-> prod[ indice ].Nterminal );
strcpy( alfa, this-> prod[ indice ].Alfa );
strcpy( Inicial, this-> prod[ indice ].inicial );
return indice;
}
Archivo 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 ERR_ASIGNACION_DE_MEMORIA -1
#define NOABRE -2
#define ERR_NO_ENCONTRADO -3
#define ERR_FUERA_DE_RANGO -4
typedef struct _PRODUCCION
{
char *Nterminal;
char *Alfa;
char *inicial;
} PRODUCCION;
// clase para el manejo de archivo
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
Iniciales Calculados
E -> (,i
E' -> +,#
T -> (,i
T' -> *,#
F -> (,i
Resultado en Consola

No hay comentarios:
Publicar un comentario