#!	/bin/sh
#***********************************************
#(C) Copyright 1992-1993; dit/upm
#  Distributed under the conditions stated in the
#  EPS General Public License (see file LICENSE)
#***********************************************
#$Log: rag,v $
# Revision 2.5  1993/10/14  18:17:22  eps
# pay attention to comments (!)
#
# Revision 2.4  1993/01/12  16:35:51  eps
# portability issues
#
# Revision 2.3  1992/01/14  15:44:11  eps
# distribution issues
#
# Revision 2.2  91/04/10  10:03:13  eps
# intermediate files are called rag_...
# 
# Revision 2.1  90/10/30  08:45:20  eps
# plenty of small fixes:
# visit, new classes, integrated tree traversal for evaluation, ...
# 
# Revision 1.8  90/08/09  15:06:17  eps
# do not generate entries for process.i when there is only VISIT
# VISIT code depends on node-type (as before) and on GRN.
# 
# Revision 1.7  90/06/04  11:54:22  eps
# language is checked for proper ordering
# new functionality VISIT
# plenty of small optimizations
# INCLUDE is explicit
# 
# Revision 1.6  90/05/10  20:25:20  eps
# new concept: VISIT
# 
# Revision 1.5  90/05/10  18:15:34  eps
# exchange evaluation of conditions and last evaluation phase
# modify awk's to work on arrays rather than on too long strings
# plenty of cosmetic changes for better lay out
# 
# Revision 1.4  90/03/16  16:55:16  eps
# it generates exactly 1 more phase than those specified by the user
# you may reference nodes, besides colours at nodes
# redundant 'break;'s eliminated (premium!)
# adclr has one argument less (-30% code size!)
# still ununderstandable! (it is worless to try)
# 
# Revision 1.3  90/02/19  19:18:12  eps
# use (void)fdclr(...) instead of ptclr (...eval(...)...)
# use find_attr for c_grn
# simplify condition evaluation
# 
# Revision 1.2  90/01/29  14:57:42  eps
# fixing license details
# 
# Revision 1.1  90/01/25  19:55:17  eps
# Initial revision
# 
#**********************************************/
#$Id: rag,v 2.5 1993/10/14 18:17:22 eps Exp $

awk '
BEGIN	{
	  state= "BEGIN"	# tool state variable
	  nar= 0		# attribute rule counter
	  nph= 1		# number of phases
	  nrr= 1
	  lhs= "_null"
	  FLIS= "spec.num"      # numbered file
	}

/^!/	{
	  print "    " $0		> FLIS
	  next
	}

/^[ \t]*$/	{
	  print "    " $0		> FLIS
	  next
	}

/^[     ]*%/	{
	  print "    " $0		> FLIS
	  next
	}

/^language/	{
	  print "    " $0		> FLIS
	  if (state !~ /^BEGIN$/){
	      print "ERROR: language not found"		> FLIS
	      state= "ERROR"
	      next
	  }
	  state= "ISPEC"
	  next
	}

/^include_lag$/	{
	  print "    " $0		> FLIS
	  if (state !~ /^ISPEC$/){
	      print "ERROR: include do not expected here" > FLIS
	      state= "ERROR"
	      next
	  }
	  state= "INCLUDE_LAG"
	  next
	}

/^include_rag$/	{
	  print "    " $0		> FLIS
	  if (state !~ /^ISPEC$/){
	      print "ERROR: include do not expected here" > FLIS
	      state= "ERROR"
	      next
	  }
	  state= "INCLUDE"
	  next
	}

/^attributes$/	{
	  print "    " $0		> FLIS
	  if (state !~ /^ISPEC$/){
	      print  "ERROR: attributes unexpected"	> FLIS
	      state= "ERROR"
	      next
	  }
	  state= "ATTRS"
	  next
	}

/^syntax$/	{
	  print "    " $0		> FLIS
	  if (state !~ /^(ISPEC|ATTRS)$/){
	      print  "ERROR: syntax unexpected"	> FLIS
	      state= "ERROR"
	      next
	  }
	  if (state ~ /^ATTRS$/) print "ATTRS " nph
	  state= "SYNTAX"
	  next
	}

/^rule$/	{
	  print "    " $0		> FLIS
	  if (state !~ /^(SYNTAX|RULEC)$/){
	      print  "ERROR: rule unexpected"	> FLIS
	      state= "ERROR"
	      next
	  }
	  rtp= ""
	  state= "RULE"
	  next
	}

/^hnode$/	{
	  print "    " $0		> FLIS
	  if (state !~ /^RULEC$/){
	      print  "ERROR: hnode unexpected"	> FLIS
	      state= "ERROR"
	      next
	  }
	  printf ("RULE %s %d %s %s %d\n", lhs, nse, tr, rtp, nrr)
	  state= "HRULE"
	  next
	}

/^ast$/	{
	  print "    " $0				> FLIS
	  if (state !~ /^(RULEC|HRULE)$/){
	      print  "ERROR: ast unexpected"		> FLIS
	      state= "ERROR"
	      next
	  }
	  if (state == "RULEC") {
	    printf ("RULE %s %d %s %s %d\n", lhs, nse, tr, rtp, nrr)
	    print "NHRULE"
	  }
	  state= "AST"
	  next
	}

/^attribution$/	{
	  print "    " $0		> FLIS
	  if (state !~ /^(RULEC|HRULE|AST)$/){
	      print  "ERROR: attribution unexpected"	> FLIS
	      state= "ERROR"
	      next
	  }
	  if (state == "RULEC") {
	    printf ("RULE %s %d %s %s %d\n", lhs, nse, tr, rtp, nrr)
	    print "NHRULE"
	  }
	  state= "AR"
	  next
	}

/^condition$/	{
	  print "    " $0		> FLIS
	  if (state !~ /^(RULEC|HRULE|AR|AST)$/){
	      print  "ERROR: condition unexpected"	> FLIS
	      state= "ERROR"
	      next
	  }
	  if (state == "RULEC") {
	    printf ("RULE %s %d %s %s %d\n", lhs, nse, tr, rtp, nrr)
	    print "NHRULE"
	  }
	  state= "COND"
	  next
	}

/visit$/	{
	  print "    " $0		> FLIS
	  if (state !~ /^(RULEC|HRULE|AR|COND|AST)$/){
	      print  "ERROR: visit unexpected"	> FLIS
	      state= "ERROR"
	      next
	  }
	  if (state == "RULEC") {
	    printf ("RULE %s %d %s %s %d\n", lhs, nse, tr, rtp, nrr)
	    print "NHRULE"
	  }
          print "VISIT " 0 " " lhs
          state= "VISIT"
          next
	}

/^end_include$/ {
	  print "    " $0		> FLIS
	  if (state !~ /^(INCLUDE_LAG|INCLUDE)$/){
	    print  "ERROR: end unexpected"	> FLIS
	    state= "ERROR"
	    next
	  }
	  state= "ISPEC"
	  next
	}

/^end_rule$/ {
	  print "    " $0		> FLIS
	  if (state !~ /^(RULEC|HRULE|AR|COND|VISIT|AST)$/){
	    print  "ERROR: end unexpected"	> FLIS
	    state= "ERROR"
	    next
	  }
	  if (state == "VISIT") {
	    print "EVISIT"
	    state= "SYNTAX"
	  }
	  else state= "SYNTAX"
	  next
	}

/^end_language$/	{
	  print "    " $0		> FLIS
	  if (state !~ /^(SYNTAX|RULEC)$/){
	      print  "ERROR: end_language unexpected"	> FLIS
	      state= "ERROR"
	      next
	  }
	  next
	}

	{
	  if (state !~ /^(AR|ARC|COND|CONDC)$/)
	    print "    " $0		> FLIS
	  if (state == "INCLUDE"){
	    print "INC " $0
	  }
	  else if (state == "ATTRS") {
            print "ATTR " $1 " " $3
	    if (nph <= $3)
	      nph= $3+1
	  }
	  else if (state == "RULE") {
	    if (substr($1,1,1) == "_")
	         tr= "_"
	    else tr= "."
	    if (lhs == $1)
	          nrr++
	    else{ lhs= $1
	          nrr= 1
	    }
	    nse= NF - 2
	    if ($0 ~ /\[.*[*+] .*\]/) {
	      nse++		# para que exista h[5]
	      rtp= "L"
	    }
	    else if ($0 ~ /\[/)
	      rtp= "O"
	    else if (rtp == "")
	      rtp= "N"
	    state= "RULEC"
	  }
	  else if (state == "RULEC") {
	    if ($0 ~ /\[.*[*+] \]/) {
	      nse++		# para que exista h[5]
	      rtp= "L"
	    }
	    else if ($0 ~ /\[/)
	      rtp= "O"
	    else if (rtp == "")
	      rtp= "N"
	    nse= nse + NF
	  }
	  else if (state == "HRULE") {
	    print "HRULE  " $0
	  }
	  else if (state == "AR") {
	      nar++
	      printf ("%3d %s\n", nar, $0) > FLIS
	      n1= split ($0, arp1, "<")
	      n2= split (arp1[1], arp2, " ")
	      if (n2 > 1)
	        print "AR " arp2[n2] " " arp2[1]
	      else
	        print "AR " arp2[1]
	      print "ARC " substr (arp1[2], 2)
	      for (i= 3; i < n2; i++)
	        print "ARC " substr (arp1[i], 2)
	      if ($0 ~ /^..*;;$/)
	         print "EAR"
	      else
	         state= "ARC"
	  }
	  else if (state == "ARC") {
	    printf ("%3d %s\n", nar, $0) > FLIS
	    print "ARC " $0
	    if ($0 ~ /^..*(;;|end)$/) {
	      print "EAR"
	      state= "AR"
	    }
	  }
	  else if (state == "VISIT") {
	    if ($0 ~ /^..*end$/) {
	         print "EVISIT"
	         state= "SYNTAX"
	    }
            else print "VISITC " $0
          }
	  else if (state == "COND") {
	    nar++
	    printf ("%3d %s\n", nar, $0) > FLIS
	    print "COND 0 _null condition"
	    if ($0 ~ /;;$/) {
	      print "CONDC " substr ($0, 1, length ($0) - 2)
	      print "ECOND"
	    }
	    else {
	      print "CONDC " $0
	      state= "CONDC"
	    }
	  }
	  else if (state == "CONDC") {
	    printf ("%3d %s\n", nar, $0) > FLIS
	    if ($0 ~ /;;$/) {
	      print "CONDC " substr ($0, 1, length ($0) - 2)
	      print "ECOND"
	      state= "COND"
	    }
	    else
	      print "CONDC " $0
	  }
	}
' $* |
sed -e '
  s/FIRST//g
  s/PREV//g
  s/NEXT//g
  s/LAST//g
  s/^COND\(.*\)\";;$/COND\1"/g
  s/^ARC[ ]*begin$/ARC  {/g
  s/^ARC[ ]*BEGIN$/ARC  {/g
  s/^ARC[ ]*end$/ARC  }/g
  s/^ARC[ ]*END$/ARC  }/g
  s/return/ return (CLR_TYPE)/g
  s/;;/;/g
  s/\$\([0-9][0-9]*\)\./$\1unknown./g
  s/^AR[^C]\(.*\)\$\([0-9][0-9]*\)\([a-z_]*\)\.\([A-Za-z0-9_]*\)/AR \2 \3 \4/g
  s/\$\([0-9][0-9]*\)\([a-z_]*\)\.\([A-Za-z0-9_]*\)/fdclr (c_\3,h[\1], nar)/g
  s/\$\([0-9][0-9]*\)\([a-z_]*\)/h[\1]/g
  { h
    s/^COND\(.*\)PRINT.*/COND\1/p
    g
    s/^COND.*\(PRINT.*\)/\1/
  }
' | 
awk '
BEGIN	{
	  nar= 1
	  EVALC= "rag_eval"
	  VISIT= "rag_visit"
	  RAGH= "rag_head"
	  print "\n\n"					> VISIT
	  print ""					> EVALC
	  print "PUBLIC CLR_TYPE"			> EVALC
	  print "eval (nar, r)"				> EVALC
	  print "    int nar;"				> EVALC
	  print "    TNODE* r;"				> EVALC
	  print "{"					> EVALC
	  print "  TNODE* h[33];"			> EVALC
	  print ""					> EVALC
	  print "  if (r == NULL) return (CLR_TYPE)NULL;"  > EVALC
	  print "  switch (nar) {"			> EVALC
	  state= "BEGIN"
	}

/^INC/	{
	  if (state !~ /^(BEGIN|INC)$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  if (state == "BEGIN"){
	   print "# include \"rag.hh\""			> RAGH
	   print "# include \"nodes.h\""		> RAGH
	   print "# include \"grc.h\""			> RAGH
	   print	""				> RAGH
	   print "IAT* grnl= NULL;"			> RAGH
	   print	""				> RAGH
	  }
	  printf("%s", $2)				> RAGH
	  for (i= 3; i <= NF; i++)
	    printf(" %s", $i)				> RAGH
	  printf("\n")					> RAGH
	  state= "INC"
	}

/^ATTR[^S]/ {
	  if (state !~ /^(BEGIN|INC|ATTR)$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  if (state == "BEGIN"){
	   print "# include \"rag.hh\""			> RAGH
	   print "# include \"nodes.h\""		> RAGH
	   print "# include \"grc.h\""			> RAGH
	   print	""				> RAGH
	   print "IAT* grnl= NULL;"			> RAGH
	   print	""				> RAGH
	  }
	  attrs[$2]= $3
	  state= "ATTR"
	}

/^ATTRS/ {
	  if (state !~ /^ATTR$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  phs= $2
	  print $0
	}

/^RULE/	{
	  if (state !~ /^(BEGIN|INC|ATTR|RULE|EAR|ECOND|EVISIT)$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  if (state == "BEGIN") {
	   print "# include \"rag.hh\""			> RAGH
	   print "# include \"nodes.h\""		> RAGH
	   print "# include \"grc.h\""			> RAGH
	   print	""				> RAGH
	   print "IAT* grnl= NULL;"			> RAGH
	   print	""				> RAGH
	   phs= 1
	   print "ATTRS 1"
	  }
	  else if (state == "INC") {
	   phs= 1
	   print "ATTRS 1"
	  }
	  else if (state ~ /^(EAR|ECOND)$/){
	    print rule " " rnph
	    for (i= 0; i < irl; i++)
	      print rl[i]
	  }
	  rule= $0
	  nhr= $3 + 1;		# size of hrule array
	  lhst= $4;		# lhs is nodo (_) or not (.) ?
	  rtp= $5;		# type list (L) or not (N) ?
	  nrr= $6;		# number of syntax rule
	  rnph= "";		# number of ar phases
	  irl= 0;		# acumulated rule
	  ihrl= 0
	  state= "RULE"
	  next
	}

/^HRULE/ {
	  if (state !~ /^RULE$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  rl[irl++]= $0
	  hrl[ihrl++]= substr ($0, 7)
	  hrule= "ON"
	  next
	}

/^NHRULE$/ {
	  if (state !~ /^RULE$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  hrule= "OFF"
	  if (lhst == "_") {
	    if (rtp == "L") {
             hrl[ihrl++]= "    h[1]= h[0]->sons;"
             hrl[ihrl++]= "    h[3]= h[0]->sons;"
             hrl[ihrl++]= "    h[4]= h[3]->brothers;"
             hrl[ihrl++]= "    h[5]= gt_ls(h[0]);"
	    }
	    else{
	     hrl[ihrl++]= "    heval (h[0], h);"
	    }
	  }
	  next
	}

/^AR[^C]/ || /^COND[^C]/ {
	  if (state !~ /^(RULE|EAR|ECOND)$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  if ($1 == "COND") {
	    rl[irl++]= "COND 0 " nar " 0 _null condition"
	    rnph= rnph "0"
	    state= "COND"
	  }
	  else if ($1 == "AR") {
	    if (attrs[$4] !~ /^[0-9]$/)
	      attrs[$4]= phs
	    if (rtp == "O")
	      $5= "OPTION"
	    else if ((rtp == "L") && ($5 != "FORALL"))
	      $5= "OPTION"
	    rl[irl++]= "AR " attrs[$4] " " nar " " $2 " " $3 " " $4 " " $5
	    rnph= rnph attrs[$4]
	    state= "AR"
	  }
	  attr= $4
	  print "  case " nar ":"		> EVALC
	  if ($2 == 0)
	    print "    h[0]= r;"		> EVALC
	  else
	     print "    h[0]= gt_ft (r);"	> EVALC
          if (hrule == "ON") {
             for (i= 0; i < ihrl; i++)
                 print hrl[i]                   > EVALC
          }
          else if (rtp == "L") {
             print "    h[1]= gt_fs (h[0]);"    > EVALC
             if ($2 == 3) {
                print "    h[3]= r;"            > EVALC
                print "    h[4]= gt_rb (h[3]);" > EVALC
             }
             else if ($2 == 4) {
                print "    h[4]= r;"            > EVALC
                print "    h[3]= gt_lb (h[4]);" > EVALC
             }
             print "    h[5]= gt_ls (h[0]);"    > EVALC
          }
          else {
             for (i= 0; i < ihrl; i++)
                 print hrl[i]                   > EVALC
          }
	  next
	}

/^ARC/	{
	  if (state !~ /^AR$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  print substr ($0, 4)			> EVALC
	  next
	}

/^EAR$/	{
	  if (state !~ /^AR$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  nar++
	  state= "EAR"
	  next
	}

/^VISIT[^C]/ {
	  if (state !~ /^(RULE|EAR|ECOND)$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  if (state ~ /^(EAR|ECOND)$/){
	    print rule " " rnph
	    for (i= 0; i < irl; i++)
	      print rl[i]
	  }
	  if (visit != "ON"){
	   print "\n\nPUBLIC void"			> VISIT
	   print "visit (r)"				> VISIT
	   print "\tTNODE*\tr;"				> VISIT
	   print "{"					> VISIT
	   print "\tTNODE*\th[33];"			> VISIT
	   print "\tint\tnar;"				> VISIT
	   print ""					> VISIT
	   print "  if (r == NULL) return;"             > VISIT
	   print "  nar= *(grnl->data[(int)(r->value0)]);" > VISIT
	   print "  switch (nar) {"			> VISIT
	   visit= "ON"
	  }
	  print "\n   case " $3 "_" nrr " :"		> VISIT
          if ($2 == 0)
            print "    h[0]= r;"                > VISIT
          else
            print "    h[0]= gt_ft (r);"        > VISIT
          if (hrule == "ON") {
             for (i= 0; i < ihrl; i++)
                 print hrl[i]                   > VISIT
          }
          else if (rtp == "L") {
             print "    h[1]= gt_fs (h[0]);"   > VISIT
             if ($2 == 3) {
                print "    h[3]= r;"            > VISIT
                print "    h[4]= gt_rb (h[3]);" > VISIT
             }
             else if ($2 == 4) {
                print "    h[4]= r;"            > VISIT
                print "    h[3]= gt_lb (h[4]);" > VISIT
             }
             print "    h[5]= gt_ls (h[0]);"    > VISIT
          }
          else {
             for (i= 0; i < ihrl; i++)
                 print hrl[i]                   > VISIT
          }
	  print "\t{"				> VISIT
	  state= "VISIT"
	  next
	}

/^VISITC/ {
	  if (state !~ /^VISIT$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  printf("\t ")				> VISIT
	  printf("%s", $2)			> VISIT
	  for (i= 3; i <= NF; i++)
	    printf(" %s", $i)			> VISIT
	  printf("\n")				> VISIT
	  next
    }

/^EVISIT$/  {
	  if (state !~ /^VISIT$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  print "\t}"				> VISIT
	  print "\tbreak;"			> VISIT
	  state= "EVISIT"
	}

/^CONDC/ {
	  if (state !~ /^(COND|CONDC|PRINT)$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  if (state == "COND"){
	       print "    if ( !(" substr($0, 6)	> EVALC
	       state= "CONDC"
	  }
	  else if (state == "CONDC"){
	       print substr($0, 7)		> EVALC
	       state= "CONDC"
	  }
	  else if (state == "PRINT")
	       print substr($0, 7)		> EVALC
	}

/^PRINT/ {
	  if (state !~ /^(COND|CONDC|PRINT)$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  print "\t)) {"			> EVALC
	  print "     report (r, c_line);"	> EVALC
	  print "     (void) fprintf (stderr, " substr ($0, 7)	> EVALC
	  state= "PRINT"
	}

/^ECOND$/ {
	  if (state !~ /^(COND|CONDC|PRINT)$/){
	      print "ERROR " $0
	      state= "ERROR"
	      next
	  }
	  if (state == "CONDC") {
	    print "\t)){"			> EVALC
	    print "     report (r, c_line);"	> EVALC
	    print "     (void) fprintf (stderr, \"error\\n\");"	> EVALC
	  }  
	  else if (state == "PRINT")
	    print "\t   );"			> EVALC
	  print "  }"				> EVALC
	  print "  return NULL;"		> EVALC
	  nar++
	  state= "ECOND"
	}

END	{
	  if (state !~ /^(EAR|ECOND|EVISIT)$/){
	      print "ERROR " $0
	      state= "ERROR"
	  }
	  if (state ~ /^(EAR|ECOND)$/){
	      print rule " " rnph
	      for (i= 0; i < irl; i++)
	        print rl[i]
	  }
	  print "     }"				> EVALC
	  print "  return (CLR_TYPE)NULL;"		> EVALC
	  print "}"					> EVALC
	  print     				        > EVALC
	  if (visit == "ON"){
	   print "  }"					> VISIT
	   print "}"					> VISIT
	  }
	}
' |
awk '

BEGIN	{ IPH= 1;	# fase inicial
	  FPH= 1;	# fase final
	  FINI= "rag_fini"
	}

/^ATTRS/ {
	  nph= $2
	  FPH= $2
	  state= "ATTRS"
	  for (i= IPH; i <= FPH; i++){
	   noPRINT[int(i)]= 1
	   FP[i]= "fp" i ".c"
	   print ""				> FP[i]
	   print "PRIVATE void"			> FP[i]
	   print "PROCES" i " (r)"		> FP[i]
	   print "    TNODE* r;"		> FP[i]
	   print "{"				> FP[i]
	   print "  TNODE* h[33];"		> FP[i]
	   print "  register i;"		> FP[i]
	   print "  int nr;"			> FP[i]
	   print "  int* grl;"			> FP[i]
	   print ""				> FP[i]
	   print "  while (r != NULL) {"			> FP[i]
	   print "    h[0]= r;"				        > FP[i]
	   print "    heval (r, h);"				        > FP[i]
	   print "    grl= grnl->data[(int)(r->value0)];"	> FP[i]
	   print "    for (i= 0; grl[i] != 0; i++) {"		> FP[i]
	   print "      nr= grl[i];"				> FP[i]
	   print "      switch (nr) {"				> FP[i]
	  }
	}

/^RULE/	{
	  nrr= $6
	  rphs= $7
	  if ((IPH == 1) && (index(rphs,"0") != 0)){
	   IPH= 0;		# fase de las condiciones
	   noPRINT[int(0)]= 1
	   FP[IPH]= "fp" IPH ".c"
	   print ""				> FP[IPH]
	   print "PRIVATE void"		> FP[IPH]
	   print "PROCES" IPH " (r)"		> FP[IPH]
	   print "    TNODE* r;"		> FP[IPH]
	   print "{"				> FP[IPH]
	   print "  TNODE* h[33];"		> FP[IPH]
	   print "  int nr;"			> FP[IPH]
	   print "  register i;"		> FP[IPH]
	   print "  int* grl;"			> FP[IPH]
	   print ""				> FP[IPH]
	   print "  while (r != NULL) {"	> FP[IPH]
	   print "    h[0]= r;"				        > FP[IPH]
	   print "    heval (r, h);"			        > FP[IPH]
	   print "    grl= grnl->data[(int)(r->value0)];"	> FP[IPH]
	   print "    for (i= 0; grl[i] != 0; i++) {"		> FP[IPH]
	   print "      nr= grl[i];"				> FP[IPH]
	   print "      switch (nr) {"				> FP[IPH]
	  }
	  if ((FPH == nph) && (index(rphs,nph+1) != 0)){
	   FPH= nph + 1;	# fase de los atributos sin fase
	   noPRINT[int(FPH)]= 1
	   FP[FPH]= "fp" FPH ".c"
	   print ""				> FP[FPH]
	   print "PRIVATE void"		> FP[FPH]
	   print "PROCES" FPH " (r)"		> FP[FPH]
	   print "    TNODE* r;"		> FP[FPH]
	   print "{"				> FP[FPH]
	   print "  TNODE* h[33];"		> FP[FPH]
	   print "  int nr;"			> FP[FPH]
	   print "  register i;"		> FP[FPH]
	   print "  int* grl;"			> FP[FPH]
	   print ""				> FP[FPH]
	   print "  while (r != NULL) {"			> FP[FPH]
	   print "    h[0]= r;"				        > FP[FPH]
	   print "    heval (r, h);"			        > FP[FPH]
	   print "    grl= grnl->data[(int)(r->value0)];"	> FP[FPH]
	   print "    for (i= 0; grl[i] != 0; i++) {"		> FP[FPH]
	   print "      nr= grl[i];"				> FP[FPH]
	   print "      switch (nr) {"				> FP[FPH]
	  }
	  if ((state == "AR") || (state == "COND")){
	    print "\t break;"				> FINI
	    for (i= IPH ; i <= FPH; i++)
	      if (index (rphs, i) != 0) {
		if (noPRINT[int(i)] == 1)
		  noPRINT[int(i)]= 0
		else
		  print "\t break;"			> FP[i]
	      }
	  }
	  if (rphs != ""){
	  print "      case " $2 "_" nrr ":"		> FINI
	  for (i= IPH; i <= FPH; i++) {
	    if (index (rphs, i) != 0)
	      print "      case " $2 "_" nrr ":"	> FP[i]
	  }
	  }
	  state= "RULE"
	}

/^HRULE/ {
	  $1= ""
	  print "\t" $0				> FINI
	  for (i= IPH; i <= FPH; i++) { 
	    if (index (rphs, i) != 0)
	      print "\t" $0			> FP[i]
	  }
	  state= "HRULE"
	}

/^AR/	{
	  rf= $2
	  if ($7 == "FORALL") {
	    print "\t h[3]= h[1];"				> FINI
	    print "\t h[4]= gt_rb (h[3]);"		  	> FINI
	    if ($4 == 3)
	      print "\t while (h[3] != NULL) {"			> FINI
	    else
	      print "\t while (h[4] != NULL) {"			> FINI
	    print "\t  adclr (-c_" $6 ", h[" $4 "], " $3 ");"	> FINI
	    print "\t  h[3]= h[4];"				> FINI
	    print "\t  h[4]= gt_rb (h[4]);"			> FINI
	    print "\t }"					> FINI

	    print "\t h[3]= h[1];"				> FP[rf]
	    print "\t h[4]= gt_rb (h[3]);"			> FP[rf]
	    if ($4 == 3)
	      print "\t while (h[3] != NULL) {"			> FP[rf]
	    else
	      print "\t while (h[4] != NULL) {"			> FP[rf]
	    print "\t  (void) fdclr (c_" $6 ", h[" $4 "], " $3 ");"	> FP[rf]
	    print "\t  h[3]= h[4];"				> FP[rf]
	    print "\t  h[4]= gt_rb (h[4]);"			> FP[rf]
	    print "\t }"						> FP[rf]
	  }
	  else if ($7 != "OPTION") {
	    print "\t adclr (-c_" $6 ", h[" $4 "], " $3 ");"	> FINI
	    print "\t (void) fdclr (c_" $6 ", h[" $4 "], " $3 ");"	> FP[rf]
	  }
	  else {
	    print "\t if (h[" $4 "] != NULL)"	> FINI
	    print "\t  adclr (-c_" $6 ", h[" $4 "], " $3 ");"	> FINI

	    print "\t if (h[" $4 "] != NULL)"	> FP[rf]
	    print "\t  (void) fdclr (c_" $6 ", h[" $4 "], " $3 ");"	> FP[rf]
	  }
	  state= "AR"
	  if (noPRINT[int(rf)] == 1)
	      noPRINT[int(rf)]= 0
	}

/^COND/	{
	  print "\t(void) eval (" $3 ", r);" > FP[0]
	  state= "COND"
	  if (noPRINT[int(0)] == 1)
	      noPRINT[int(0)]= 0
	}

END	{
	  print "\t break;"				> FINI
	  print "      default:"			> FINI
	  print "\t assert ((1 <= nr) && (nr <= LAST_RULE));"	> FINI
	  print "      }"				> FINI
	  print "    } /* end of while (ngr != NULL) */" > FINI
	  print "    r= succ (r, PREORDER);"		> FINI
	  print "  } /* end of while (r != NULL) */"	> FINI
	  print "} /* end of PROCESINI */"		> FINI
	  for(i= IPH; i <= FPH; i++){
	    if (noPRINT[int(i)] != 1)
	      print "\t break;"				> FP[i]
	   print "      default:"			> FP[i]
	   print "\t assert ((1 <= nr) && (nr <= LAST_RULE));"	> FP[i]
	   print "      }"				> FP[i]
	   print "    } /* end of while (ngr != NULL) */"	> FP[i]
	   print "    r= succ (r, PREORDER);"		> FP[i]
	   print "  } /* end of while (r != NULL) */"	> FP[i]
	   print "} /* end of PROCES" i " */"		> FP[i]
	  }
	  print ""					> "rag_C"
	  print "PUBLIC void"				> "rag_C"
	  print "rag (r)"				> "rag_C"
	  print "    TNODE* r;"				> "rag_C"
	  print "{"					> "rag_C"
	  print "  PROCESINI (r);"			> "rag_C"
	  for (i= 1; i < FPH; i++)
	    print "  PROCES" i " (r);"			> "rag_C"
	  if (IPH == 0)
	   print "  PROCES0 (r);"			> "rag_C"
	  print "  if (ragerrors == 0)"			> "rag_C"
	  print "    todo (r);"				> "rag_C"
	  print "} /* end of rag */"			> "rag_C"
	}
'


cat - > rag_F1c << ENDOFF

PRIVATE void
PROCESINI (r)
    TNODE* r;
{
  TNODE* h[33];
  register 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) {
ENDOFF

for file in `ls -r fp?.c`
do
  rm $file
  break
done

if test -f fp0.c -o -f fp1.c
then
  cat   rag_head rag_F1c rag_fini fp?.c rag_eval rag_visit rag_C > rag.c
  rm -f rag_head rag_F1c rag_fini fp?.c rag_eval rag_visit rag_C
else
  cat   rag_head rag_F1c rag_fini rag_eval rag_visit rag_C > rag.c
  rm -f rag_head rag_F1c rag_fini rag_eval rag_visit rag_C
fi

exit 0
