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

char stack[100];
int top = -1;

void push(char c) {
  stack[++top] = c;
}

char pop() {
  if (top == -1) return '\0';
  return stack[top--];
}

char peek() {
  if (top == -1) return '\0';
  return stack[top];
}

void printStack() {
  for (int i = 0; i <= top; i++) {
     printf("%c", stack[i]);
  }
}

int getRowIndex(char c) {
   if (c == 'S') return 0;
   if (c == 'B') return 1;
   return -1;
}

int getColIndex(char c) {
   if (c == 'a') return 0;
   if (c == 'b') return 1;
   if (c == '$') return 2;
   return -1;
}

int main() {

  char table[2][3][10] = {
     { "aBa", "", "" },
     { "", "bB", "#" }
  };

  char input[100];
  printf("Enter the input string (end with $): ");
  scanf("%s", input);

  push('$');
  push('S');

  int ip = 0;
  printf("\n%-20s %-20s %-20s\n", "Stack", "Input Buffer", "Action");
  printf("------------------------------------------------------------\n");

  while (peek() != '$') {

  printStack();
  printf("\t\t\t");
  printf("%s", input + ip);
  printf("\t\t\t");

  char X = peek();
  char a = input[ip];

  if (X == a) {
     printf("Match %c\n", a);
     pop();
     ip++;
  }
  else if (X >= 'a' && X <= 'z') {

     printf("\nSyntax Error: Terminal mismatch! Expected %c but found %c\n", X, a);
     return 1;
  }
  else {

     int r = getRowIndex(X);
     int c = getColIndex(a);

     if (r == -1 || c == -1 || strlen(table[r][c]) == 0) {
        printf("\nSyntax Error: No parsing table entry for [%c, %c]\n", X, a);
        return 1;
     }

     char *prod = table[r][c];
     printf("%c -> %s\n", X, prod);
     pop();


     if (strcmp(prod, "#") != 0) {
        for (int i = strlen(prod) - 1; i >= 0; i--) {
           push(prod[i]);
        }
     }
  }
 }


 printStack();
 printf("\t\t\t");
 printf("%s", input + ip);
 printf("\t\t\t");

 if (peek() == '$' && input[ip] == '$') {
    printf("Success\n");
    printf("\nResult: String successfully Parsed & Accepted!\n");
 } else {
    printf("Error\n");
    printf("\nResult: Syntax Error. Input rejected.\n");
 }

 return 0;
}
