/*+-----------------------------------------------------+
  | ANALISE SINTATICA ASCENDENTE LR(K)                  |
  | Por Luiz Eduardo da Silva                           |
  +-----------------------------------------------------+*/

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


struct {
  char acao;
  int ind;
} T[50][30];


struct {
  char elem;
  int ind;
} P[20];

char col[30];
char reg[10][20];

void traco (int i) {
  int k;
  for (k = 0; k < i; k++)
		printf ("-");
  printf ("\n");
}
void main (void)
{
  FILE *Arquivo;
  int i, j, k, termino, reduzido, indice, ind, tam, passo;
  char sentenca[40], pilha[60], cadeia[40], str[40];
  char s,simboloreduzido, acao, Caractere;
  char S[80];
  P[0].elem = 'e'; P[0].ind = 0;
  i = termino = reduzido = 0;

{
 if ((Arquivo = fopen ("c:\\Teste.txt","r")) == NULL)
	{
	printf ("Erro abertura do arquivo de regras\n");
	exit(1);
	}
	fgets(S,80,Arquivo);
	i=0;
	do
	 {
	fgets (S,80,Arquivo);
	if (S[0] != '#')
		strcpy (T[i++],S);
		printf (S);
	} while (S[0] != '#');

	//fgets(S,80,Arquivo);
	i=0;
	do
	 {
	fgets (S,80,Arquivo);
	if (S[0] != '#')
		{
		strcpy (reg[i++],S);
		printf (S);
		}
	} while (S[0] != '#');

	do
	 {
	fgets (S,80,Arquivo);
	if (S[0] != '#')
		strcpy (col[i++],S);
		printf (S);
	} while (S[0] != '#');
	}

  printf ("\nDigite uma sentenca: ");
  scanf ("%s", sentenca);
  strcat (sentenca, "#");
  indice = 0;
  passo = 0;
  printf ("%5s %-40s %-20s %s\n",
			  "PASSO", "PILHA", "CADEIA DE ENTRADA", "ACAO");
  traco (79);

  while (!termino) {
	 if (reduzido)
		 s = simboloreduzido;
	 else
		 s = sentenca[indice];
	 for (j=0; col[j] != s; j++);
	 acao = T[P[i].ind][j].acao;
	 ind  = T[P[i].ind][j].ind;
	 strcpy (cadeia, "");
	 for (k = indice; sentenca[k]; k++) {
		 sprintf (str, "%c", sentenca[k]);
		 strcat (cadeia, str);
	 }
	 strcpy (pilha, "");
	 for (k = 0; k<=i; k++) {
		 sprintf (str, "%c%d", P[k].elem, P[k].ind);
		 strcat (pilha, str);
	 }
	 printf ("%5d %-40s %-20s %c%d\n",
				 passo++, pilha, cadeia, acao, ind);

	 switch (acao) {
		 case 'e': i++;
					  P[i].elem = s;
					  P[i].ind = ind;
					  if (reduzido)
							reduzido = 0;
					  else
							indice++;
					  break;
		 case 'r': tam = strlen(reg[ind-1]);
                 i = i - tam + 4;
                 reduzido = 1;
                 simboloreduzido = reg[ind-1][0];
                 break;
       case 'a': termino = 1;
                 printf ("Cadeia reconhecida\n\n");
                 break;
       case ' ': printf ("ERRO : cadeia nao reconhecida\n\n");
                 exit(1);
    }
  } 
}
