#include <fstream.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>

#define MAX                    999       
#define PROG_SIZE                  9999
#define MAX_SYMBOLES               999
#define MAX_LABLES                 999
#define FIELD_SIZE                 99
#define MAX_INSTRUCTIONS           999
#define MAX_FIELDS_PER_INSTRUCTION 99
#define WORD_SIZE                  99
#define END_LABLE          998
#define MAX_FORMATTING_CHARS       9
#define     NUMBER_OF_FORMATTING_CHARS 6
#define MAX_KEYWORDS               99
#define NUMBER_OF_KEYWORDS         8
#define FORMATTING_CHAR_SIZE       2
#define KEYWORD_SIZE             99
#define MAX_PRINT_INDEX          99
#define LOOP_STACK_SIZE            999
#define UP                 1
#define DOWN                     0
#define BALANCED                 2
#define INT                3
#define CHAR                     4
#define COMMAND_STRING_SIZE      99

void *Wait(void)
{
//    cout<<"\nPress a key...";
      getchar();
      return(NULL);
}

class String
{
      private :
                char *Str;
      public :
//          String(int);     
            inline void *Constructer(int);                  //LENGTH_OF_STRING
            inline void *Set(char *);
            inline char *Get(void);
            inline char Get_I(int);
            inline void *Make_Dot(void);
            inline void *Increment_Dot(void);
            inline char *Get_Next_Symbole(char *);
            inline char *Get_First_Symbole(void);
            inline char Get_First_Char(void);
            inline char Get_Last_Char(void);
            inline void *Reset(void);
            inline int Equals(char *);
};


void *String::Constructer(int i=MAX)
{
      Str=new char[i]; 
      memset(Str,'\0',sizeof(Str));
      return(NULL);
}

int String::Equals(char *c)
{
      int Flag;
      if(strcmp(c,Str)==0)
      {
            Flag=1;
      }
      else
      {
            Flag=0;
      }
      return(Flag);
}    

void *String::Set(char *c)   
{
      memset(Str,'\0',sizeof(Str));
      strcpy(Str,c);
      return(NULL);
}

char *String::Get(void)
{
      return(Str);
}

char String::Get_I(int i)
{
      return(Str[i]);
}

void *String::Reset(void)
{
      memset(Str,'\0',sizeof(Str));
      return(NULL);
}

char String::Get_First_Char(void)
{
      return(Str[0]);
}

char String::Get_Last_Char(void)
{
      return(Str[strlen(Str)-1]);
}

void *String::Make_Dot(void)
{
//    char Str[99];
        char Tmp_Str[MAX];
      int i;
      int Space_Counter;
//    memset(Str,'\0',sizeof(Str));
//    strcpy(Str,"Anand K Chauhan");
      memset(Tmp_Str,'\0',sizeof(Tmp_Str));
      for(i=0,Space_Counter=0;Space_Counter!=2;i++)
      {
            if(Str[i]==' ')
            {
                  Space_Counter++;
            }
            Tmp_Str[i]=Str[i];
      }
      strcat(Tmp_Str,(char *)". ");
      for(i+=2;i<(strlen(Str)+2);Tmp_Str[i]=Str[i-2],i++);
//    cout<<"\n"<<Tmp_Str;

      memset(Str,'\0',sizeof(Str));

      strcpy(Str,Tmp_Str);   

      return(NULL);

}

           

void *String::Increment_Dot(void)

{

 

//    char Str[24]=". Name  Anand K Chauhan";

        char Tmp_Str[MAX];

        char Tmp_Str1[MAX];

      memset(Tmp_Str,'\0',sizeof(Tmp_Str));

      memset(Tmp_Str1,'\0',sizeof(Tmp_Str1));

      int i;

      int j;

      for(i=0;Str[i]!='.';i++)

      {

            if(Str[i]!='.')

            {

                  Tmp_Str[i]=Str[i];

            }

      }

      strcat(Tmp_Str,(char *)" ");

      for(i+=2;Str[i]!=' ';Tmp_Str[i-2]=Str[i],i++);

      strcat(Tmp_Str,(char *)" . ");

      for(j=0;i<strlen(Str);Tmp_Str1[j]=Str[i+1],i++,j++); 

      strcat(Tmp_Str,Tmp_Str1);

//    cout<<"\nInput = "<<Str;

//    cout<<"\n\n";

//    cout<<"\nOutput = "<<Tmp_Str;

//    cout<<"\n";

      memset(Str,'\0',sizeof(Str));

      strcpy(Str,Tmp_Str);

      return(NULL);

}

 

char *String::Get_First_Symbole(void)                      

{

//    int i;

//    char Str[99];

        char Tmp_Str[MAX];

      char *Token;

        char Symbole[MAX];

      memset(Tmp_Str,'\0',sizeof(Tmp_Str));

      strcpy(Tmp_Str,Str);

//    memset(Str,'\0',sizeof(Str));

      memset(Symbole,'\0',sizeof(Symbole));

//    strcpy(Str,(char *)"Anand Kumar Chauhan");

      Token=strtok(Str,(char *)" ");

      strcpy(Symbole,Token);

//    cout<<"\n"<<Symbole;

      strcpy(Str,Tmp_Str);

      return((char *)Symbole);

}

                 

char *String::Get_Next_Symbole(char *Sample)

{

//    char Str[99];

        char Tmp_Str[MAX];

//    char Sample[99];

//    int Max;

      char *Token;

        char Ans[MAX];

        char Result[MAX];

      int Offset;

      int Space_Count;

      int Flag;

      int i;

      int j;

//    cout<<"\nIn core symbole = "<<Sample;
//    memset(Str,'\0',sizeof(Str));

//    memset(Sample,'\0',sizeof(Sample));

      memset(Ans,'\0',sizeof(Ans));

      memset(Result,'\0',sizeof(Result));

//    strcpy(Str,(char *)"Anand . Kumar Chauhan ");

      strcpy(Tmp_Str,Str);

//    strcpy(Sample,(char *)".");

      if(Str[strlen(Str)-2]!='.')

      {

            Token=strtok(Str,(char *)" ");

            Offset=0;

            i=0;

            while(Token)

            {

                  i++;

                  Token=strtok(NULL,(char *)" ");

                  if(Token)

                  {

                        if(strcmp((char *)Sample,(char *)Token)==0)

                        {    

                              Offset=i;

                        }

                  }

            }

            Offset++;

            strcpy(Str,Tmp_Str);

            for(i=0,Space_Count=0;Space_Count<Offset;i++)

            {

                  if(Str[i]==' ')

                  {

                        Space_Count++;

                  }

            }

            for(j=0,Flag=1;(Flag);j++,i++)

            {

                  if(Str[i]!=' ')

                  {                

                        Ans[j]=Str[i];

                  }

                  else

                  {

                        Flag=0;

                  }

            }          

//          cout<<"\nAns = "<<Ans<<" "<<strlen(Ans);

//          cout<<"\n\n";

            if(strlen(Ans)==0)

            {

                  strcpy(Result,(char *)"NOT_FOUND");

            }

            else

            {

                  strcpy(Result,Ans);

            }

      }

      else

      {    

            strcpy(Result,(char *)"NOT_FOUND");

      }    

//    cout<<"\nFinally = "<<Ans;
      return((char *)Ans);

}

                       

 

 

class String_Set

{

      private :

                String *String_Sets;

            int Index;    
      public :

//          String_Set(int,int);                      //NUMBER_OF_STRINGS,LENGTH_OF_EACH_STRING
            inline void *Constructer(int,int);        //NUMBER_OF_STRINGS,LENGTH_OF_EACH_STRING
            inline void *Set(int,char *);             //RULE_NUMBER , VALUE

            inline char *Get(int);                    //RULE_NUMBER

            inline void *Make_Dot(int);               //STATE_NUMBER,RULE_NUMBER

            inline void *Increment_Dot(int);          //STATE_NUMBER   

            inline char *Get_Next_Symbole(int,char *);      //STATE_NUMBER, CURRENT_SYMBOLE

            inline char *Get_First_Symbole(int);     

            inline int Set_Unique(int,char *);

            inline int Equals(int,char *);                        //SUBSTRING_NUMBER
            inline char Get_First_Char(int);
            inline char Get_Last_Char(int);
            inline void *Reset(int);

};

 

/*   
String_Set::String_Set(int i=MAX,int j=MAX)
{
      int k;
      String_Sets=new String[i];
      for(k=0;k<i;String_Sets[k].Constructer(j),k++);
//    void *String_Set::Set(int i,char *c)

}
*/

void *String_Set::Constructer(int i=MAX,int j=MAX)
{
      int k;
      String_Sets=new String[i];
      for(k=0;k<i;String_Sets[k].Constructer(j),k++);
      return(NULL);
//    void *String_Set::Set(int i,char *c)

}


/*{

      String_Sets[i].Set(c);

      return(NULL);

}

*/
 

int String_Set::Equals(int i,char *c)
{
      return(String_Sets[i].Equals(c));
}

void *String_Set::Reset(int j)

{

      int i;     

      for(i=0;i<Index;String_Sets[i].Reset(),i++);

      return(NULL);

}

 

int String_Set::Set_Unique(int v,char *c)

{

      int i;

      int Flag;

      int Found;

      int Result;

      for(Found=0,Flag=1,i=0;(Flag);i++)

      {

            if(strlen(String_Sets[i].Get())==0)

            {

                  Flag=0;

            }

            else

            {

                  if(strcmp(String_Sets[i].Get(),c)==0)

                  {

                        Found=1;

                  }

            }

      }

      if(!Found)

      {

            String_Sets[v].Set(c);

            Result=1;

      }

      else

      {

            Result=0;

      }

      return(Result);

}

 

void *String_Set::Set(int i,char *c)
{
      String_Sets[i].Set(c);
      return(NULL);
}
     
char *String_Set::Get(int i)

{

      return(String_Sets[i].Get());

}

 

void *String_Set::Make_Dot(int i)

{

      String_Sets[i].Make_Dot();

      return(NULL);

}

 

void *String_Set::Increment_Dot(int i)

{

      String_Sets[i].Increment_Dot();

      return(NULL);

}

 

char *String_Set::Get_First_Symbole(int i)

{

      return(String_Sets[i].Get_First_Symbole());

}

 

char *String_Set::Get_Next_Symbole(int i,char *c)

{

//    cout<<"\nhere it is = "<<String_Sets[i].Get_Next_Symbole(c);

//    cout<<"\nfor i,c as "<<i<<" , "<<c<<" it is = "<<String_Sets[i]->Get_Next_Symbole(c);
//    Wait();
      return(String_Sets[i].Get_Next_Symbole(c));

}

char String_Set::Get_First_Char(int i)
{
      return(String_Sets[i].Get_First_Char());
}


char String_Set::Get_Last_Char(int i)
{
      return(String_Sets[i].Get_Last_Char());
}

class Integer_Set
{
      private :
            int *String;
      public :
            Integer_Set(int);
            inline void *Reset(void);
            inline void *Constructer(int);
            inline void *Set_I(int,int);
            inline void *Set_I_Unique(int,int);
            inline int Get_I(int);
};

Integer_Set::Integer_Set(int i=MAX)
{
      String=new int[i];     
      memset(String,0x0,sizeof(String));
}

void *Integer_Set::Reset(void)
{
      memset(String,0x0,sizeof(String));
      return(NULL);          
}

void *Integer_Set::Constructer(int i=MAX)
{
      String=new int[i];
      memset(String,0x0,sizeof(String));
      return(NULL);
}    

void *Integer_Set::Set_I(int Index,int Value)
{
      String[Index]=Value;
      Index++;
      return(NULL);
}

void *Integer_Set::Set_I_Unique(int Index,int Value)
{
      int Flag;
      int i;
      for(i=0,Flag=0;i<MAX;i++)
      {
            if(String[i]==Value)
            {
                  Flag=1;
            }
      }
      if(!Flag)
      {
            String[Index]=Value;
      }
      return(NULL);
}

int Integer_Set::Get_I(int Index)
{
      return(String[Index]);
}

class Stack
{
      private :
            int Top_Of_Stack;
            int Array[LOOP_STACK_SIZE];
      public :
            Stack(void);
            inline void *Reset(void);
            inline int Push(int);
            inline int Pop(void);
};

Stack::Stack(void)
{
      Top_Of_Stack=-1;
}

void *Stack::Reset(void)
{
      Top_Of_Stack=-1;
      memset(Array,0,sizeof(Array));
      return(NULL);
}
                       
int Stack::Push(int n)
{
      int Result;
      Top_Of_Stack++;
      if(Top_Of_Stack>=LOOP_STACK_SIZE)
      {
            Result=-1;
      }
      else
      {
            Result=1;
      }
      if(Result)
      {
            Array[Top_Of_Stack]=n;
      }
      return(Result);
}


int Stack::Pop(void)
{
      int Result;
      Result=Array[Top_Of_Stack];
      Top_Of_Stack--;
//    cout<<"\nTOS = "<<Top_Of_Stack;
      if(Top_Of_Stack<-1)
      {
            Result=-1;
      }
      return(Result);
}