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

#define DELIMITER       1
#define VARIABLE        2
#define INTEGER_LITERAL 3
#define TRUE            1
#define FALSE           0

char Current_Token[80],*Expression;
int Token_Type;
struct Var_Type {   int Used,Value; } Var[26];
struct Map_Type {   char Name; int Index; } Map[26];

void Eval_1(int *Answer), Eval_2(int *Answer), Eval_3(int *Answer);
void Eval_4(int *Answer), Eval_5(int *Answer), Eval_6(int *Answer);
void ParseError(int Error);
int Get_Token(void);
int Equal(char *S1,char *S2);

int Equal(S1,S2)

char *S1,*S2;

{
   return(!strcmp(S1,S2));
}

void Eval_1(Answer)

int *Answer;

{
   if (Get_Token()) Eval_2(Answer);
   else ParseError(2);
}

/* Token In Current_Token, Exp Ptr to next item */

void Eval_2(Answer)

int *Answer;

{
   int Temp,OldAnswer;
   char Op[80],*OldPosition;

   Eval_3(Answer);

   OldAnswer = *Answer;
   OldPosition = Expression;

   do
   {  if (Get_Token())
      {
         strcpy(Op,Current_Token);
         if (Equal(Op,"|"))
         {
	    if (Get_Token())
	    {
	       Eval_3(&Temp);
	       OldAnswer = *Answer = Temp || *Answer;
	       OldPosition = Expression;
	    }
         }
         else
         {
            *Answer = OldAnswer;
            Expression = OldPosition;
         }
      }
      else Op[0] = '\0';
   }
   while (Equal(Op,"|") && *Expression);
}

void Eval_3(Answer)

int *Answer;

{
   int Temp,OldAnswer;
   char Op[80],*OldPosition;

   Eval_4(Answer);

   OldAnswer = *Answer;
   OldPosition = Expression;

   do
   {
      if (Get_Token())
      {
         strcpy(Op,Current_Token);
         if (Equal(Op,"&"))
         {
            if (Get_Token())
	    {
	       Eval_4(&Temp);
	       OldAnswer = *Answer = Temp && *Answer;
	       OldPosition = Expression;
	    }
         }
         else
         {
            Expression = OldPosition;
            *Answer = OldAnswer;
         }
      }
      else Op[0] = '\0';
   }
   while (Equal(Op,"&") && *Expression);
}

void Eval_4(Answer)

int *Answer;

{
   if (Equal(Current_Token,"-"))
   {
      if (Get_Token())
      {
	 Eval_5(Answer);
	 if (*Answer == 0) *Answer = 1;
	 else *Answer = 0;
      }
      else ParseError(3);
   }
   else Eval_5(Answer);
}

void Eval_5(Answer)

int *Answer;

{
   if (Equal(Current_Token,"("))
   {
      Get_Token();
      Eval_2(Answer);
      if (!Equal(Current_Token,")")) ParseError(1);
      Get_Token();
   }
   else Eval_6(Answer);
}

void Eval_6(Answer)

int *Answer;

{
   if (Token_Type == INTEGER_LITERAL) *Answer = atoi(Current_Token);
   else if (Token_Type == VARIABLE) *Answer = Var[Current_Token[0] - 'A'].Value;
}

int Get_Token()

{

   char *Temp;

   Temp = Current_Token;

   if (*Expression)
   {
      if (isalpha(*Expression))
      {
	 Token_Type = VARIABLE;
	 while(isalpha(*Expression)) *Temp++ = *Expression++;
      }
      else if (isdigit(*Expression))
      {
         Token_Type = INTEGER_LITERAL;
         while(isdigit(*Expression)) *Temp++ = *Expression++;
      }
      else if (strchr("&|-()",*Expression))
      {
         *Temp++ = *Expression++;
	 Token_Type = DELIMITER;
      }
      else
      {
         return(0);
      }

      *Temp = '\0';
      return(1);

   }
   return(0);
}

void ParseError(int Error)
{
   static char *e[] = {
			 "Syntax Error",
			 "Unbalanced Paranthesis",
			 "No Expression Present"
			 "No Operand For Unary Minus"
			 "Incomplete Expression"
			 "Invalid Argument Type"
		      };
   printf("Error: %s",e[Error]);
}

void Init_Vars()
{
   int i;
   for (i=0;i<26;Var[i++].Used = 0);
}

int Get_Vars(Exp)

char *Exp;

{
   int Sum,i;
   Sum = 0;

   while (*Exp)
   {
      if (isalpha(*Exp))
      {
	 if (islower(*Exp)) *Exp = toupper(*Exp);
         Var[*Exp-'A'].Used = 1;
      }
      Exp++;
   }
   for (i=0;i<26;Sum+=Var[i++].Used);
   return (Sum);
}

void Map_Vars()

{
   int M,i;

   M = 0;
   for (i = 0; i<26; i++)
   {
      if (Var[i].Used)
      {
	 Map[M].Name = (i + 'A');
	 Map[M++].Index = i;
      }
   }
}

void Set_Vars(State,Num_Vars)

int State,Num_Vars;

{
   int i,Mask;
   for (i=0;i<Num_Vars;i++)
   {
      Mask = (1<<(Num_Vars-1))>>i;
      if ((Mask|State) == State) Var[Map[i].Index].Value = 1;
      else Var[Map[i].Index].Value = 0;
   }
}

main (argc,argv)

int argc;
char **argv;

{
   int i,j,k,l,answer,Num_Vars;

   for(i=2;i<=argc;i++)
   {
      Init_Vars();
      Num_Vars = Get_Vars(argv[i-1]);
      Map_Vars();
      printf("\n\n");
      for(k=0;k<Num_Vars;printf("%c",Map[k++].Name));
      printf(" Value\n--------------------------------\n");
      for (j=0;j<(1<<(Num_Vars));j++)
      {
         Expression = argv[i-1];
	 Set_Vars(j,Num_Vars);
	 for(l=0;l<Num_Vars;l++) printf("%d",Var[Map[l].Index].Value);
         Eval_1(&answer);
         printf(" %d\n",answer);
      }
   }
}

