# include "rag.hh"
# include "nodes.h"
# include "grc.h"

IAT* grnl= NULL;

# include "swbus.h"
int cntrule= 1;

PRIVATE void
PROCESINI (r)
    TNODE* r;
{
  TNODE* h[33];
  /*KJT 22/01/23: added "int" type */
  register int i;
  int nr;
  int* grl;

  while (r != NULL) {
    h[0]= r;
    heval (r, h);
    grl= grnl->data[(int)(r->value0)];
    for (i= 0; grl[i] != 0; i++) {
     nr= grl[i];
     switch (nr) {
      case _rules_1:
	 h[3]= h[1];
	 h[4]= gt_rb (h[3]);
	 while (h[3] != NULL) {
	  adclr (-c_nrule, h[3], 1);
	  h[3]= h[4];
	  h[4]= gt_rb (h[4]);
	 }
	 if (h[1] != NULL)
	  adclr (-c_ngrc, h[1], 2);
	 if (h[0] != NULL)
	  adclr (-c_start, h[0], 3);
	 if (h[1] != NULL)
	  adclr (-c_idgrc, h[1], 4);
	 h[3]= h[1];
	 h[4]= gt_rb (h[3]);
	 while (h[4] != NULL) {
	  adclr (-c_ngrc, h[4], 5);
	  h[3]= h[4];
	  h[4]= gt_rb (h[4]);
	 }
	 h[3]= h[1];
	 h[4]= gt_rb (h[3]);
	 while (h[4] != NULL) {
	  adclr (-c_idgrc, h[4], 6);
	  h[3]= h[4];
	  h[4]= gt_rb (h[4]);
	 }
	 if (h[0] != NULL)
	  adclr (-c_idgrc, h[0], 7);
	 break;
      case _rule_1:
	 adclr (-c_rlhs, h[0], 8);
	 adclr (-c_ndid, h[0], 9);
	 break;
      case _rule_2:
	 if (h[0] != NULL)
	  adclr (-c_rlhs, h[0], 10);
	 if (h[0] != NULL)
	  adclr (-c_ndid, h[0], 11);
	 break;
      case lhs_1:
	 adclr (-c_type, h[0], 12);
	 break;
      case lhs_2:
	 adclr (-c_type, h[0], 13);
	 break;
      case rhs_2:
	 adclr (-c_type, h[0], 14);
	 adclr (-c_nterms, h[0], 15);
	 break;
      case rhs_3:
	 adclr (-c_type, h[0], 16);
	 adclr (-c_nterms, h[0], 17);
	 break;
      case rhs_4:
	 adclr (-c_type, h[0], 18);
	 adclr (-c_nterms, h[0], 19);
	 break;
      case rhs_5:
	 adclr (-c_type, h[0], 20);
	 adclr (-c_nterms, h[0], 21);
	 break;
      case rhs_6:
	 adclr (-c_nterms, h[0], 22);
	 break;
      case _repp_1:
	 if (h[0] != NULL)
	  adclr (-c_intid, h[0], 23);
	 break;
      case _repa_1:
	 if (h[0] != NULL)
	  adclr (-c_intid, h[0], 24);
	 break;
      case _repp_sep_1:
	 if (h[0] != NULL)
	  adclr (-c_intid, h[0], 25);
	 break;
      case _repa_sep_1:
	 if (h[0] != NULL)
	  adclr (-c_intid, h[0], 26);
	 break;
      case _secuence_1:
	 if (h[0] != NULL)
	  adclr (-c_nsec, h[0], 27);
	 if (h[0] != NULL)
	  adclr (-c_type, h[0], 28);
	 break;
      case term_1:
	 adclr (-c_nsec, h[0], 29);
	 adclr (-c_type, h[0], 30);
	 break;
      case term_2:
	 adclr (-c_nsec, h[0], 31);
	 adclr (-c_type, h[0], 32);
	 break;
      case term_3:
	 adclr (-c_nsec, h[0], 33);
	 adclr (-c_type, h[0], 34);
	 break;
      case term_4:
	 if (h[0] != NULL)
	  adclr (-c_nsec, h[0], 35);
	 if (h[0] != NULL)
	  adclr (-c_type, h[0], 36);
	 break;
      case _option_1:
	 if (h[0] != NULL)
	  adclr (-c_intid, h[0], 37);
	 break;
      case _terminal_1:
	 adclr (-c_tndx, h[0], 38);
	 break;
      default:
	 assert ((1 <= nr) && (nr <= LAST_RULE));
      }
    } /* end of while (ngr != NULL) */
    r= succ (r, PREORDER);
  } /* end of while (r != NULL) */
} /* end of PROCESINI */

PUBLIC CLR_TYPE
eval (nar, r)
    int nar;
    TNODE* r;
{
  TNODE* h[33];

  if (r == NULL) return (CLR_TYPE)NULL;
  switch (nar) {
  case 1:
    h[0]= gt_ft (r);
    h[1]= gt_fs (h[0]);
    h[3]= r;
    h[4]= gt_rb (h[3]);
    h[5]= gt_ls (h[0]);
   return (CLR_TYPE) cntrule++;
  case 2:
    h[0]= gt_ft (r);
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);
   return (CLR_TYPE) 1;
  case 3:
    h[0]= r;
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);
   return (CLR_TYPE)  fdclr (c_rlhs,h[1], nar);
  case 4:
    h[0]= gt_ft (r);
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);
   return (CLR_TYPE) buildgrc ((int)  fdclr (c_rlhs,h[1], nar),
					  (int)  fdclr (c_ngrc,h[1], nar),
					  (int)  fdclr (c_nrule,h[1], nar),
					  (int)  fdclr (c_ndid,h[1], nar));
  case 5:
    h[0]= gt_ft (r);
    h[1]= gt_fs (h[0]);
    h[4]= r;
    h[3]= gt_lb (h[4]);
    h[5]= gt_ls (h[0]);
  if ((int)fdclr (c_rlhs,h[3], nar) == (int)fdclr (c_rlhs,h[4], nar))
			       return (CLR_TYPE) ((int)fdclr (c_ngrc,h[3], nar) + 1);
			 else  return (CLR_TYPE) 1;
  case 6:
    h[0]= gt_ft (r);
    h[1]= gt_fs (h[0]);
    h[4]= r;
    h[3]= gt_lb (h[4]);
    h[5]= gt_ls (h[0]);
   return (CLR_TYPE) buildgrc ((int)  fdclr (c_rlhs,h[4], nar),
					   (int)  fdclr (c_ngrc,h[4], nar),
					   (int)  fdclr (c_nrule,h[4], nar),
					   (int)  fdclr (c_ndid,h[4], nar));
  case 7:
    h[0]= r;
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);
   return (CLR_TYPE) lastgrc ((int) fdclr (c_nrule,h[5], nar));
  case 8:
    h[0]= r;
    heval (h[0], h);
   return (CLR_TYPE) fdclr (c_lexv,h[1], nar);
  case 9:
    h[0]= r;
    heval (h[0], h);
  if (h[1]->type == tnode)
			return (CLR_TYPE) ITadd((int)fdclr (c_lexv,h[1], nar), ndl);
		  else  return (CLR_TYPE) -1;
  case 10:
    h[0]= r;
    heval (h[0], h);
   return (CLR_TYPE) fdclr (c_lexv,h[1], nar);
  case 11:
    h[0]= r;
    heval (h[0], h);
  if (h[1]->type == tnode)
			return (CLR_TYPE) ITadd((int)fdclr (c_lexv,h[1], nar), ndl);
		  else  return (CLR_TYPE) -1;
  case 12:
    h[0]= r;
   return (CLR_TYPE) R_PHYLA;
  case 13:
    h[0]= r;
   return (CLR_TYPE) R_NODE;
  case 14:
    h[0]= r;
   return (CLR_TYPE) R_REPP;
  case 15:
    h[0]= r;
   return (CLR_TYPE) 1;
  case 16:
    h[0]= r;
   return (CLR_TYPE) R_REPA;
  case 17:
    h[0]= r;
   return (CLR_TYPE) 1;
  case 18:
    h[0]= r;
   return (CLR_TYPE) (R_REPP | R_REPP_SEP);
  case 19:
    h[0]= r;
   return (CLR_TYPE) 1;
  case 20:
    h[0]= r;
   return (CLR_TYPE) (R_REPA | R_REPA_SEP);
  case 21:
    h[0]= r;
   return (CLR_TYPE) 1;
  case 22:
    h[0]= r;
   return (CLR_TYPE) fdclr (c_nsec,h[0], nar);
  case 23:
    h[0]= r;
    heval (h[0], h);
   return (CLR_TYPE) bintid(R_REPP);
  case 24:
    h[0]= r;
    heval (h[0], h);
   return (CLR_TYPE) bintid(R_REPA);
  case 25:
    h[0]= r;
    heval (h[0], h);
   return (CLR_TYPE) bintid(R_REPP_SEP);
  case 26:
    h[0]= r;
    heval (h[0], h);
   return (CLR_TYPE) bintid(R_REPA_SEP);
  case 27:
    h[0]= r;
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);
  {
	TNODE*	tmp;
	int	nsec= 0;
	for (tmp= h[1]; tmp != NULL; tmp= tmp->brothers)
	     nsec += (int)fdclr(c_nsec, tmp, -1);
	 return (CLR_TYPE) nsec;
  }
  case 28:
    h[0]= r;
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);
  {
	TNODE*	tmp;
	int	tpsec= 0;
	for (tmp= h[1]; tmp != NULL; tmp= tmp->brothers)
	     tpsec |= (int)fdclr(c_type, tmp, -1);
	 return (CLR_TYPE) tpsec;
  }
  case 29:
    h[0]= r;
   return (CLR_TYPE) 1;
  case 30:
    h[0]= r;
   return (CLR_TYPE) R_SEC_PH;
  case 31:
    h[0]= r;
   return (CLR_TYPE) 1;
  case 32:
    h[0]= r;
   return (CLR_TYPE) R_SEC;
  case 33:
    h[0]= r;
   return (CLR_TYPE) 0;
  case 34:
    h[0]= r;
   return (CLR_TYPE) R_SEC_TERM;
  case 35:
    h[0]= r;
   return (CLR_TYPE) 1;
  case 36:
    h[0]= r;
   return (CLR_TYPE) R_SEC_PH;
  case 37:
    h[0]= r;
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);
   return (CLR_TYPE) bintid(R_OPT);
  case 38:
    h[0]= r;
    heval (h[0], h);
   return (CLR_TYPE) ITadd((int)fdclr (c_lexv,h[0], nar), term_lis);
     }
  return (CLR_TYPE)NULL;
}






PUBLIC void
visit (r)
	TNODE*	r;
{
	TNODE*	h[33];
	int	nar;

  if (r == NULL) return;
  nar= *(grnl->data[(int)(r->value0)]);
  switch (nar) {

   case _language_1 :
    h[0]= r;
    heval (h[0], h);
	{
	 grheader (((TNODE*)h[2] != NULL) ? (char*)fdclr (c_block,h[2], nar) : NULL,
	 (int)fdclr (c_start,h[5], nar));
	 visit(h[5]);
	 grtail ();
	}
	break;

   case _rules_1 :
    h[0]= r;
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);
	{
	 TNODE* ndrule;
	 for (ndrule= h[1]; ndrule != NULL; ndrule= ndrule->brothers)
	 visit(ndrule);
	}
	break;

   case _rule_1 :
    h[0]= r;
    heval (h[0], h);
	{
	 visit((TNODE*)h[2]);
	 fprintf(fgrm, "%-23s :\n", SymbolTable->data[(int)fdclr (c_lexv,h[1], nar)]);
	 psyntax(h[2]);
	 opena();
	 actions(h[1], h[2]);
	 fprintf(fgrm, "\t putgrn(%d);\n", (int)fdclr (c_nrule,h[0], nar));
	 closea();
	 fprintf(fgrm, "\t;\n\n");
	}
	break;

   case _rule_2 :
    h[0]= r;
    heval (h[0], h);
	{
	 visit((TNODE*)h[2]);
	 fprintf(fgrm, "%-23s :\n", SymbolTable->data[(int)fdclr (c_lexv,h[1], nar)]);
	 psyntax(h[2]);
	 opena();
	 if ((TNODE*)h[3] != NULL)
	 fprintf(fgrm,"%s", fdclr (c_block,h[3], nar));
	 else actions (h[1], h[2]);
	 fprintf(fgrm, "\t putgrn(%d);\n", (int)fdclr (c_nrule,h[0], nar));
	 closea();
	 fprintf(fgrm, "\t;\n\n");
	}
	break;

   case _repp_1 :
    h[0]= r;
    heval (h[0], h);
	{
	 fprintf(fgrm, "%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t %s\n", SymbolTable->data[(int)fdclr (c_lexv,h[1], nar)]);
	 fprintf(fgrm, "\t;\n\n");
	 fprintf(fgrm, "%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t %s %s\n", (char*)fdclr (c_intid,h[0], nar),
	 SymbolTable->data[(int)fdclr (c_lexv,h[1], nar)]);
	 fprintf(fgrm, "\t{ if (errorcount == 0) stlrlink (); }\n");
	 fprintf(fgrm, "\t;\n\n");
	}
	break;

   case _repa_1 :
    h[0]= r;
    heval (h[0], h);
	{
	 fprintf(fgrm, "%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t /* empty */\n");
	 fprintf(fgrm, "\t{ ndput(tNULL); }\n");
	 fprintf(fgrm, "\t;\n\n");
	 fprintf(fgrm, "%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t %s %s\n", (char*)fdclr (c_intid,h[0], nar),
	 SymbolTable->data[(int)fdclr (c_lexv,h[1], nar)]);
	 opena();
	 fprintf(fgrm, "\t if (stpick(1)->type == tNULL) {stswap(); stpop();}\n");
	 fprintf(fgrm, "\t else stlrlink();\n");
	 closea();
	 fprintf(fgrm, "\t;\n\n");
	}
	break;

   case _repp_sep_1 :
    h[0]= r;
    heval (h[0], h);
	{
	 fprintf(fgrm, "%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t %s\n", SymbolTable->data[(int)fdclr (c_lexv,h[1], nar)]);
	 fprintf(fgrm, "\t;\n\n");
	 fprintf(fgrm, "%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t %s %s %s\n", (char*)fdclr (c_intid,h[0], nar),
	 SymbolTable->data[(int)fdclr (c_lexv,h[2], nar)],
	 SymbolTable->data[(int)fdclr (c_lexv,h[1], nar)]);
	 fprintf(fgrm, "\t{ if (errorcount == 0) stlrlink (); }\n");
	 fprintf(fgrm, "\t;\n\n");
	}
	break;

   case _repa_sep_1 :
    h[0]= r;
    heval (h[0], h);
	{
	 fprintf(fgrm, "%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t /* empty */\n");
	 fprintf(fgrm, "\t{ ndput(tNULL); }\n");
	 fprintf(fgrm, "\t;\n\n");
	 fprintf(fgrm, "%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t A%s\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t;\n\n");
	 fprintf(fgrm, "A%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t %s\n", SymbolTable->data[(int)fdclr (c_lexv,h[1], nar)]);
	 fprintf(fgrm, "\t;\n\n");
	 fprintf(fgrm, "A%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t A%s %s %s\n", (char*)fdclr (c_intid,h[0], nar),
	 SymbolTable->data[(int)fdclr (c_lexv,h[2], nar)],
	 SymbolTable->data[(int)fdclr (c_lexv,h[1], nar)]);
	 fprintf(fgrm, "\t{ if (errorcount == 0) stlrlink (); }\n");
	 fprintf(fgrm, "\t;\n\n");
	}
	break;

   case _secuence_1 :
    h[0]= r;
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);
	{
	 TNODE* tmp;
	 for (tmp= h[1]; tmp != NULL; tmp= tmp->brothers)
	 if (tmp->type == toption)
	 visit(tmp);
	}
	break;

   case _option_1 :
    h[0]= r;
    h[1]= gt_fs (h[0]);
    h[5]= gt_ls (h[0]);
	{
	 TNODE* tmp;
	 int allterm= TRUE;
	 fprintf(fgrm, "%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t /* empty */\n");
	 fprintf(fgrm, "\t{ ndput (tNULL); }\n");
	 fprintf(fgrm, "\t;\n\n");
	 fprintf(fgrm, "%-23s :\n", (char*)fdclr (c_intid,h[0], nar));
	 fprintf(fgrm, "\t");
	 for (tmp= h[1]; tmp != NULL; tmp= tmp->brothers){
	 fprintf(fgrm, " %s", SymbolTable->data[(int)fdclr(c_lexv, tmp, -1)]);
	 if (tmp->type != tterminal) allterm= FALSE;
	 }
	 fprintf(fgrm, "\n");
	 if (allterm)
	 fprintf(fgrm, "\t{ ndput (tNULL); }\n");
	 fprintf(fgrm, "\t;\n\n");
	}
	break;
  }
}

PUBLIC void
rag (r)
    TNODE* r;
{
  PROCESINI (r);
  if (ragerrors == 0)
    todo (r);
} /* end of rag */
