jueves, 14 de enero de 2010

Automata de Pila


>>>>  Programa .cpp  <<<<<<
#include
#include "Pila.h"

using namespace std;

#define E1    -1
#define E2 -2
#define E3 0
#define Maximo   100

char *Prod[12] = { "T", "T'", "E", "E'", "F", "+", "*", "#", "I", "(", ")", "$" };

int tblAutomata[6][6]={
{0,99,99,0,99,99},
{99,1,99,99,2,2},
{3,99,99,3,99,99},
{99,5,4,99,5,5},
{6,99,99,7,99,99},
{99,99,99,99,99,100}};

enum Producciones { T, T_P, E, E_P, F, ADD, MUL, V, ID, PAR_A, PAR_C, FC };



CStack Pila( sLong(100) ); // DECLARACION DE LA PILA

int AutoTabla( const char* cadena );




void main()
{
   char cadena_ent[ Maximo ];
  
   cout << "*******AUTOMATA DE PILA**********"<<
     cout << "INCERTA CADENA: ";
     cin.getline( cadena_ent, Maximo);    
     strcat( cadena_ent,"$" ); //AGREGA SIMBOLO AL FINAL DE LA CADENA
    
     switch(AutoTabla(cadena_ent))
      {
        case E1: cout << "Error en la sintaxis" << endl; break;
        case E2: cout << "Caracter no valido" <
        case E3: cout << "ACEPTADA"<
      }
    
     Pila.sDelete();//ELIMINA LA PILA
}

int AutoTabla( const char *cadena )
{
   int i=0,tamCad=strlen(cadena);
   long elem, col=0,fil=0,pa=0;
   char *tmp;
  
   Pila.sPush( (long)&Prod[ FC ][ 0 ],NULL ); // INSERTA SIMBOLO DE FIN DE CADENA
   Pila.sPush( (long)&Prod[ E ][ 0 ], NULL ); // INSERTA INCIAL DE L APILA
  
   while(cadena[i])
    {
       Pila.sPeek( elem, NULL );
       tmp=(char*)elem;
      
       if(tmp[0]==cadena[i] || (isalpha(cadena[i]) && tmp[0]=='I'))
        {
          if( cadena[ i ] == '$' )
            if( !pa ) return E3;
else
return E1;
        
          if( cadena[ i ] == '(' )
 pa++;
          else
 if( cadena[ i ] == ')' ) pa--;
          
          Pila.sPop( elem,NULL );
          i++;
 continue;
        }
 
 
 
 
 
 
  ///////////////////////////////////////////////////////////////////////////////////////////////
  /////////////DA VALORES A FINA Y COLUMNA PARA RECORRER LA TABLA////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////
        
       if( !strcmp((char*)elem,Prod[E]))
  fil = 0;  
       else
  if( !strcmp( (char*)elem,Prod[E_P]) )
  fil = 1;
  else
  if( !strcmp( (char*)elem,Prod[T]) )
  fil = 2;
  else
  if( !strcmp( (char*)elem,Prod[T_P]) )
  fil = 3;
  else
  if( !strcmp( (char*)elem,Prod[F]) )
  fil = 4;
  else
  if( !strcmp( (char*)elem,Prod[FC]) )
  fil = 5;
      
       if( isalpha( cadena[ i ] ) )
  col = 0;
       else
  if( cadena[ i ] == '+' )
  col = 1;
  else
  if( cadena[ i ] == '*' )
  col = 2;
  else
  if( cadena[ i ] == '(' )
  col = 3;
  else if( cadena[ i ] == ')' )
  col = 4;
  else
  if( cadena[ i ] == '$' ) col = 5;

  else return E2;

  ///////////////////////////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////



       switch( tblAutomata[fil][col] )//RECORRE LA TABLA
        {
          case 0:Pila.sPop( elem,NULL ); Pila.sPush( (long)&Prod[E_P][0],NULL );Pila.sPush( (long)&Prod[T][0],NULL );
            break;          
          case 1:Pila.sPop( elem,NULL);Pila.sPush( (long)&Prod[E_P][0],NULL );Pila.sPush( (long)&Prod[T][0],NULL );
 Pila.sPush( (long)&Prod[ADD][0],NULL );
            break;          
          case 2:Pila.sPop( elem,NULL );break;
 case 3:Pila.sPop( elem,NULL );Pila.sPush( (long)&Prod[T_P][0],NULL );Pila.sPush( (long)&Prod[F][0],NULL );
           break;          
          case 4:Pila.sPop( elem,NULL );Pila.sPush( (long)&Prod[T_P][0],NULL );Pila.sPush( (long)&Prod[F][0],NULL );
 Pila.sPush( (long)&Prod[MUL][0],NULL );
 break;
 case 5:Pila.sPop( elem,NULL );break;        
          case 6:Pila.sPop( elem,NULL );Pila.sPush( (long)&Prod[ID][0],NULL );break;          
          case 7:Pila.sPop( elem,NULL );Pila.sPush( (long)&Prod[PAR_C][0],NULL );Pila.sPush( (long)&Prod[E][0],NULL );
             Pila.sPush( (long)&Prod[PAR_A][0],NULL );break;          
          case 99: return E2;
        
          case 100: return E3;
        }


    }

   return E1;
}

>>>>>>  Programa en .h   <<<<<<<


#ifndef STACK_CPP_H
#define STACK_CPP_H

#ifndef NULL
 #define NULL 0
#endif

  // constantes de excepciones
#define STACK_SUCCESS    0
#define STACK_EMPTY     -1
#define STACK_FULL      -2
#define STACK_ERR_MEM   -3
#define STACK_OUT_RANGE -4

#define sShort(code) (short)code
#define sLong(value) (long)value

typedef struct _STACK_SEGMENT // segmento de pila
{
  long dwData;
  void *vpAux;
  
} STACK_SEGMENT;
  
class CStack // clase manejadora de pila
{
   private:
    STACK_SEGMENT **sSegments;
    long dwSP;
    long dwSSize;
    short wExCod;
    
   public:
    CStack( long sMaxSize );
    CStack( short wCode ) : wExCod(wCode) { this-> sSegments = NULL; }
    ~CStack();
    
    const char* what() const throw();
    
    short sGetExCode();
    long GetSP();
    long GetStackMaxSize();
    long sPush( long dwData, const void** vpAux );
    long sPop( long& dwData, void** vpAux );
long sPeek( long& dwData, void** vpAux );
    long sDelete();
};
  // constructor
CStack::CStack( long sMaxSize )
  this-> dwSP      = -1;
  this-> wExCod    = 0;
  this-> dwSSize   = sMaxSize;
  this-> sSegments = NULL;
}

CStack::~CStack() { this-> sDelete(); } // Destructor

inline long CStack::GetSP() { return this-> dwSP; } // obtiene el puntero de pila

inline long CStack::GetStackMaxSize() { return this-> dwSSize;} // obtiene el tamaƱo maximo de pila

inline short CStack::sGetExCode() { return this-> wExCod; } // obtiene el codigo de excepcion

long CStack::sPush( long dwData, const void** vpAux ) // inserta un elemento en la pila
{
   STACK_SEGMENT **sAux;
   long i;
      // si la pila esta llena
   if( this-> dwSP >= this-> dwSSize-1 ) throw CStack( sShort(STACK_FULL) );

   this-> dwSP++;
   
   if( !this-> dwSP ) // si es el primer elemento
    {
      this-> sSegments = new STACK_SEGMENT* [this-> dwSP+1];
      if( !this-> sSegments ) throw CStack( sShort(STACK_ERR_MEM) );
      
      this-> sSegments[ this-> dwSP ] = new STACK_SEGMENT;
      if( !this-> sSegments[ this-> dwSP ] ) throw CStack( sShort(STACK_ERR_MEM) );
    }
   
   else // numero de elementos > 1
    {
      sAux = new STACK_SEGMENT* [this-> dwSP+1];
      if( !sAux ) throw CStack( sShort(STACK_ERR_MEM) );
      
      sAux[ this-> dwSP ] = new STACK_SEGMENT;
      if( !sAux[ this-> dwSP ] ) throw CStack( sShort(STACK_ERR_MEM) );
      
      for( i=0 ; i < this-> dwSP; i++ ) sAux[ i ] = this-> sSegments[ i ];
      
      delete[] this-> sSegments;
      
      this-> sSegments = sAux;
    }

   this-> sSegments[ this-> dwSP ]-> dwData = dwData;
   
   if( vpAux )
     this-> sSegments[ this-> dwSP ]-> vpAux  = (void*)*vpAux;
   else
     this-> sSegments[ this-> dwSP ]-> vpAux  = NULL;
   
   return this-> dwSP;
} // fin de sPush()

long CStack::sPop( long& dwData, void** vpAux ) // extrae un elemento de la pila
{
   STACK_SEGMENT **sAux;
   long i, tmpSP;
      // si la pila esta vacia
   if( this-> dwSP < 0 ) throw CStack( sShort(STACK_EMPTY) );
     
   dwData  = this-> sSegments[ this-> dwSP ]-> dwData;
   if( vpAux ) *vpAux = this-> sSegments[ this-> dwSP ]-> vpAux;
 
   if( !this-> dwSP ) // si hay un elemento
    {  
      delete this-> sSegments[ this-> dwSP ];
      delete[] this-> sSegments;
      
      this-> dwSP = -1;
    }
   
   else // si hay mas de 1 elemento
    { 
      sAux = new STACK_SEGMENT* [ this-> dwSP ];
      if( !sAux ) throw CStack( sShort(STACK_ERR_MEM) );
      
      delete this-> sSegments[ this-> dwSP ];
   
      this-> dwSP--;
 
      for( i=0; i <= this-> dwSP; i++ ) sAux[ i ] = this-> sSegments[ i ];
   
      delete[] this-> sSegments;
      
      this-> sSegments = sAux;
    }
    
   return this-> dwSP;
} // fin de sPop()
  // obtiene el elemeto en la cima sin extraerlo
long CStack::sPeek( long& dwData, void** vpAux )
{
   if( this-> dwSP < 0 ) throw CStack( sShort(STACK_EMPTY) );
   
   dwData = this-> sSegments[ this-> dwSP ]-> dwData;
   if( vpAux ) *vpAux  = this-> sSegments[ this-> dwSP ]-> vpAux;
   
   return this-> dwSP;
}

long CStack::sDelete() // Elimina la pila
{
   if( this-> sSegments )
    {
      for( ; this-> dwSP >= 0; this-> dwSP-- ) delete this-> sSegments[ this-> dwSP ];

      delete[] this-> sSegments;
    }
    
   return STACK_SUCCESS;
}

const char* CStack::what() const throw() // devuelve el texto de la excepcion
{
   switch( this-> wExCod )
    {
      case STACK_SUCCESS: return "Exito";
      case STACK_FULL:    return "Pila llena";
      case STACK_EMPTY:   return "Pila Vacia";
      case STACK_ERR_MEM: return "Error de asignacion de memoria";
    }
   
   return NULL;
}

#endif



0 comentarios:

Publicar un comentario

Suscribirse a Enviar comentarios [Atom]

<< Inicio