/* recursive pfn generator */
#define GNC()   ch=*++txt
#define NO()    printf("error\n"), exit(1)

static char *txt;
static char ch;

static void 
Reduce(int n) {
  switch (n) {
  case 1: printf("|"); break;
  case 3: printf("&"); break;
  case 5: printf("~"); break;
  case 7: printf("t"); break;
  case 8: printf("f"); break;
  }
}

static void P(void);       /* C forward declarations */
static void D(void);
static void C(void);
static void N(void);
static void B(void);

static void 
D(void) {
  C();
  Reduce(2);
  while (ch=='|') {
    GNC();                    /* discard | */
    C();
    Reduce(1);
  }
}

static void 
C(void) {
  N();
  Reduce(4);
  while (ch=='&') {
    GNC();                    /* discard & */
    N();
    Reduce(3);
  }
}

static void 
N(void) {
  if (ch == '~') {
    GNC();                    /* discard ~ */
    B();
    Reduce(5);
  } else {
     B();
    Reduce(6);
  }
}

static void 
B(void) {
  switch (ch) {
  case 't':
    GNC();                    /* discard t */
    Reduce(7);
    break;
  case 'f':
    GNC();                    /* discard f */
    Reduce(8);
    break;
  case '(':
    GNC();                    /* discard ( */
    D();
    if (ch != ')') NO();
    GNC();                    /* discard ) */
    Reduce(9);
    break;
  default:
    NO();
    break;
  }
}

static void 
P(void) {
  D();
  if (ch != 0) NO();          /* null terminated */
  Reduce(0);
}

int 
main(int argc, char **argv) {
  txt = argv[1];
  ch  = *txt;                 /* first char */
  P();
  return 0;
}


Created: March 29, 2001
Last modified: May 29, 2007