#include <stdio.h>
#include <ctype.h>
#include <string.h>

/*************************************************************************/
/*                                                                       */
/*                 SINTÁXIS Y SEMÁNTICA DE LENGUAJES                     */
/*                                                                       */
/*  AUTOR:                                                               */
/*         BIANCHI, Fabricio                                             */
/*                                                                       */
/*  COMISIÓN: 208                                                        */
/*                                                                       */
/*************************************************************************/
// versión 0.7 26/06/10

/*------ PROTOTIPOS ------*/

int Busca_Estado_Acep(char cEstadoAcep[], char cEstado); // devuelve 1 si el estado es de aceptacion
void Procesar_Cadena(char *cEstado, int *iCant, char cEstadoAcep[], char cTabla[][3]);



/*------------ MAIN ------------*/

int main()
{
 // c: char - i: int
 char cEstado;
 char cEstadoIni;
 char cEstadoAcep[10];
 char cTabla[10][3];
 char cControl;
 char rta;
 int iCant;
 int iI=0;		
 int iJ=0;
 
 
 printf("Ingrese la cantidad de estados: "); 
 scanf("%d", &iCant);
 getchar(); 


 printf("Ingrese el estado inicial: "); 
 scanf("%c", &cEstadoIni);
 getchar();
 cEstadoIni=toupper(cEstadoIni);
 cEstado=cEstadoIni; /*No ingreso directamente cEstado porque tengo que saber cuanto vale
                       el estado inicial cuando de la opcion de seguir ingresando cadenas.*/
 
 printf("\nIngrese el/los estado/s de aceptacion (ingrese '*' para finalizar): \n");
 scanf("%c",&cControl);
 getchar();
 cControl=toupper(cControl);
 cEstadoAcep[iI]=cControl;/*iI vale 0*/
 
 // usando la variable auxiliar cControl, me aseguro no ingresar un asterisco en el arreglo
 for(iI=1;iI<10;iI++) 
 {   
   scanf("%c",&cControl);
   getchar();
   cControl=toupper(cControl);
   if(cControl!='*')
     cEstadoAcep[iI]=cControl;
   else 
     iI=10;
 }
 
 // Lleno la columna 0 con los nombres de los estados
 cTabla[0][0]='A';
 for(iI=0; iI<iCant; iI++)
 {
   cTabla[iI+1][0]= (cTabla[iI][0])+1;
 } 

 printf("\nIngrese los estados correspondientes a la tabla del AFD. Ingrese 'x' en lugar de vacío\n");/*VER*/
 for(iI = 0; iI < iCant; iI ++)
 {
    for(iJ = 1; iJ < 3; iJ++)
    {
       printf("Fila %d | Columna %d\n", iI, iJ);
       scanf("%c", &cTabla[iI][iJ]);
       getchar();
       cTabla[iI][iJ]=toupper(cTabla[iI][iJ]);
    }
 }
 
// Ingreso de palabras
 
 rta='S';
 while(rta=='S')
 {
	Procesar_Cadena(&cEstado, &iCant, cEstadoAcep, cTabla);
	printf("Desea continuar ingresando cadenas? (S/N)\n");
	scanf("%c", &rta);
	getchar();
	rta=toupper(rta);
	cEstado=cEstadoIni;
 }

 return 0;
}// FIN MAIN





/*------ BUSCA ESTADO ACEP ------------*/

int Busca_Estado_Acep(char cEstadoAcep[], char cEstado)
{
	int iI;
	int iEncontrado=0;
	for(iI=0;iI<10;iI++) 
	{
		if(cEstadoAcep[iI]==cEstado)
			iEncontrado=1;
	}

	if(iEncontrado==1)

		return 1;
	else

	return 0;
}




/*------ PROCESAR CADENA ------------*/

void Procesar_Cadena(char *cEstado, int *iCant, char cEstadoAcep[], char cTabla[][3])
{
	char cadena[20];
	int iI;
	int iJ;
	int incorrecta;
	int iFila;
	int iCol; 
 
 printf("\nIngrese la palabra: (* para salir)\n"); 
 
 scanf("%s",cadena);
 getchar();
 
 for(iI=0; (iI<strlen(cadena)); iI++)

 { 		
   // obtengo columna
   incorrecta=0;
   if(cadena[iI]=='a')
     iCol=1;
   else if (cadena[iI]=='b')
     iCol=2;
   else
   	{
   	 incorrecta=1; // me aseguro que no sea de aceptación colocando esta bandera
     break;
		}

  	// obtengo fila del estado en el que estoy posicionado
   for (iJ=0; iJ<*iCant; iJ++)
		{
      if(cTabla[iJ][0] == *cEstado)
				iFila = iJ;
		}

   if(cTabla[iFila][iCol] != 'X') // obtengo mi nuevo estado, si existe
     *cEstado = cTabla[iFila][iCol];
   else
   	 {
   	 	incorrecta=1;
     	break;
     }
 }

(Busca_Estado_Acep(cEstadoAcep, *cEstado)&&(incorrecta==0))?printf("\nCadena aceptada\n"):printf("Cadena NO aceptada\n");
}

