%{
/* Revision 2000/07/00  16:32:00  kjt
   changed YYMAXDEPTH to 512 */

# include "swbus.h"
# define YYMAXDEPTH      512
# define YYSTYPE         yystype
# define putgrn(n)       (void)ITadd(n, gl)
# define class(nt)       { cls= 0; xxc= nt-1;   \
               for (xc= 0; xc < nt; xc++, xxc--)    \
                             if (stpick(xc)->type != tNULL) \
                 cls += (1 << xxc);}
# define ndput(tp)   { stput(tp);   \
               if (gn != NULL){gn->value0=  \
                  (CLR_TYPE)IAT_IT_add(gl, grnl); \
                  gl->size= 0;} \
               gn= (sttype() == tNULL) ? NULL : sttop(); }
# define ndterm(tp, val) { stput (tp);  \
                       staclr (c_lexv, (CLR_TYPE)val.name); \
                       staclr (c_line, (CLR_TYPE)val.line);}

IT* gl;
TNODE*  gn;
int cls;
int xc;
int xxc;

%}

%token R 260
%token INTEGER 261
%token OF 262
%token IDENTIFIER 263
%token SPECIAL 264

%start PTCS


%%

I1repp                  :
	 PTC
	;

I1repp                  :
	 I1repp PTC
	{ if (errorcount == 0) stlrlink (); }
	;

PTCS                    :
	 I1repp
	{
	if (errorcount == 0)
	{
	 class(1);
	 ndput(tPTCS);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(1);
	}
	}
	;

I2opt                   :
	 /* empty */
	{ ndput (tNULL); }
	;

I2opt                   :
	 sobjs
	;

I3opt                   :
	 /* empty */
	{ ndput (tNULL); }
	;

I3opt                   :
	 range
	;

PTC                     :
	 I2opt ':' objs ':' I3opt ';'
	{
	if (errorcount == 0)
	{
	 class(3);
	 if (sttype() == tNULL) stpop();
	 else if (stpick(1)->type == tNULL) {stswap(); stpop();}
	 else stlrlink();
	 if (sttype() == tNULL) stpop();
	 else if (stpick(1)->type == tNULL) {stswap(); stpop();}
	 else stlrlink();
	 ndput(tPTC);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(2);
	}
	}
	;

I4repp_sep              :
	 Csubobj
	;

I4repp_sep              :
	 I4repp_sep ';' Csubobj
	{ if (errorcount == 0) stlrlink (); }
	;

sobjs                   :
	 I4repp_sep
	{
	if (errorcount == 0)
	{
	 class(1);
	 ndput(tsobjs);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(3);
	}
	}
	;

I5repp_sep              :
	 obj
	;

I5repp_sep              :
	 I5repp_sep ',' obj
	{ if (errorcount == 0) stlrlink (); }
	;

Csubobj                 :
	 I5repp_sep
	{
	if (errorcount == 0)
	{
	 class(1);
	 ndput(tCsubobj);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(4);
	}
	}
	;

I6repp_sep              :
	 obj
	;

I6repp_sep              :
	 I6repp_sep ';' obj
	{ if (errorcount == 0) stlrlink (); }
	;

objs                    :
	 I6repp_sep
	{
	if (errorcount == 0)
	{
	 class(1);
	 ndput(tobjs);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(5);
	}
	}
	;

I7opt                   :
	 /* empty */
	{ ndput (tNULL); }
	;

I7opt                   :
	 path
	;

I8opt                   :
	 /* empty */
	{ ndput (tNULL); }
	;

I8opt                   :
	 range
	;

obj                     :
	 I7opt label I8opt
	{
	if (errorcount == 0)
	{
	 class(3);
	 if (sttype() == tNULL) stpop();
	 else if (stpick(1)->type == tNULL) {stswap(); stpop();}
	 else stlrlink();
	 if (sttype() == tNULL) stpop();
	 else if (stpick(1)->type == tNULL) {stswap(); stpop();}
	 else stlrlink();
	 ndput(tobj);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(6);
	}
	}
	;

obj                     :
	 R label
	{
	if (errorcount == 0)
	{
	 class(1);
	 ndput(tobj);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(7);
	}
	}
	;

path                    :
	 '(' label ')'
	{
	if (errorcount == 0)
	{
	 class(1);
	 ndput(tpath);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(8);
	}
	}
	;

range                   :
	 minl maxl
	{
	if (errorcount == 0)
	{
	 class(2);
	 stlrlink ();
	 ndput(trange);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(9);
	}
	}
	;

minl                    :
	 INTEGER
	{
	if (errorcount == 0)
	{
	 ndput(tminl);
	 staclr (c_lexv, (CLR_TYPE)$1.name);
	 staclr (c_line, (CLR_TYPE)$1.line);
	 putgrn(10);
	}
	}
	;

maxl                    :
	 INTEGER
	{
	if (errorcount == 0)
	{
	 ndput(tmaxl);
	 staclr (c_lexv, (CLR_TYPE)$1.name);
	 staclr (c_line, (CLR_TYPE)$1.line);
	 putgrn(11);
	}
	}
	;

I9opt                   :
	 /* empty */
	{ ndput (tNULL); }
	;

I9opt                   :
	 experiment_list
	;

label                   :
	 gate_name I9opt
	{
	if (errorcount == 0)
	{
	 class(2);
	 if (sttype() == tNULL) stpop();
	 else if (stpick(1)->type == tNULL) {stswap(); stpop();}
	 else stlrlink();
	 ndput(tlabel);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(12);
	}
	}
	;

I10repp                 :
	 exp
	;

I10repp                 :
	 I10repp exp
	{ if (errorcount == 0) stlrlink (); }
	;

experiment_list         :
	 I10repp
	{
	if (errorcount == 0)
	{
	 class(1);
	 ndput(texperiment_list);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(13);
	}
	}
	;

I11opt                  :
	 /* empty */
	{ ndput (tNULL); }
	;

I11opt                  :
	 OF sort_id
	;

exp                     :
	 '!' val_id I11opt
	{
	if (errorcount == 0)
	{
	 class(2);
	 if (sttype() == tNULL) stpop();
	 else if (stpick(1)->type == tNULL) {stswap(); stpop();}
	 else stlrlink();
	 ndput(texp);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(14);
	}
	}
	;

exp                     :
	 '?' sort_id
	{
	if (errorcount == 0)
	{
	 class(1);
	 ndput(texp);
	 sttop()->value1= (CLR_TYPE)cls;
	 if (stpick(1)->type == tNULL)
	      {stswap(); stpop();}
	 else stsflink ();
	 putgrn(15);
	}
	}
	;

gate_name               :
	 IDENTIFIER
	{
	if (errorcount == 0)
	{
	 ndput(tgate_name);
	 staclr (c_lexv, (CLR_TYPE)$1.name);
	 staclr (c_line, (CLR_TYPE)$1.line);
	 putgrn(16);
	}
	}
	;

val_id                  :
	 SPECIAL
	{
	if (errorcount == 0)
	{
	 ndput(tval_id);
	 staclr (c_lexv, (CLR_TYPE)$1.name);
	 staclr (c_line, (CLR_TYPE)$1.line);
	 putgrn(17);
	}
	}
	;

val_id                  :
	 IDENTIFIER
	{
	if (errorcount == 0)
	{
	 ndput(tval_id);
	 staclr (c_lexv, (CLR_TYPE)$1.name);
	 staclr (c_line, (CLR_TYPE)$1.line);
	 putgrn(18);
	}
	}
	;

val_id                  :
	 INTEGER
	{
	if (errorcount == 0)
	{
	 ndput(tval_id);
	 staclr (c_lexv, (CLR_TYPE)$1.name);
	 staclr (c_line, (CLR_TYPE)$1.line);
	 putgrn(19);
	}
	}
	;

sort_id                 :
	 IDENTIFIER
	{
	if (errorcount == 0)
	{
	 ndput(tsort_id);
	 staclr (c_lexv, (CLR_TYPE)$1.name);
	 staclr (c_line, (CLR_TYPE)$1.line);
	 putgrn(20);
	}
	}
	;

%%

PRIVATE int
yylex ()
{
    token *tk;

   tk = gtk ();
   yylval = tk->yylval;
   return tk->type;
}

PUBLIC TNODE*
bast ()
{
   gl= ITcreate (4, 2, 1);
   gn= NULL;
   (void)yyparse();
   if (gn != NULL) gn->value0= (CLR_TYPE)IAT_IT_add(gl, grnl);
   return sttop();
}
