
# line 2 "pdbParse.y"

/* try /local/mouse/bin/localsym */

/* defines to cover the global yacc symbols */

#define yyact		_pdbYYact
#define yychar		_pdbYYchar
#define yychk		_pdbYYchk
#define yydebug		_pdbYYdebug
#define yydef		_pdbYYdef
#define yyerrflag	_pdbYYerrflag
#define yyexca		_pdbYYexca
#define yylex		_pdbYYlex
#define yylexinit	_pdbYYlexinit
#define yylval		_pdbYYlval
#define yynerrs		_pdbYYnerrs
#define yypact		_pdbYYpact
#define yyparse		_pdbYYparse
#define yypgo		_pdbYYpgo
#define yyr1		_pdbYYr1
#define yyr2		_pdbYYr2
#define yyval		_pdbYYval

#include <stdio.h>
#include <ctype.h>
#include <strings.h>

#include "../h/cdefs.h"
#include "pdb.h"

extern double strtod();

#define IBUFSIZE  1024

static FILE* inputFd;
static char inputBuf[IBUFSIZE];
static char* inputBufPtr;
static int lineno;
static char errMsgBuf[256];
static int errMsgSet = 0;
static PdbSet *rootSet;

#define YYSTYPE yystype
typedef struct {
	PdbSet *set;
	PdbPar *par;
	union {
	    double d;
	    int i;
	    char* s;
	 } u;
	int previousComma;
	int lineno;
} yystype;

void *hashFind();
void *hashInsert();

extern int yychar;

static char* tokenStr();
static printParName();
static char* copystr();
static yylexinit();
static yylex();
static matchNumber();

static int yyerror(str)
char* str;
{
	char *syntaxErrMsg = "syntax error";

	if (!errMsgSet)
	 { if (strncmp (str, syntaxErrMsg, strlen(syntaxErrMsg)) == 0)
	    { sprintf (errMsgBuf, "line %d: syntax error, near %s\n", 
		   		  lineno, tokenStr(yychar));
	    }
	   else
	    { sprintf (errMsgBuf, "%s\n", str);
	    }
	 }
	errMsgSet = 1;
}

# define DOUBLE 257
# define STRING 258
# define INTEGER 259
# define IDENTIFIER 260
# define LEFTPAREN 261
# define RIGHTPAREN 262
# define LEFTANGLE 263
# define RIGHTANGLE 264
# define EQUAL 265
# define COMMA 266
# define QUESTION_MARK 267
# define COLON 268
# define ASSIGN 269
# define PLUS 270
# define MINUS 271
# define TIMES 272
# define DIVIDE 273
# define ERR 274
#define yyclearin yychar = -1
#define yyerrok yyerrflag = 0
extern int yychar;
extern int yyerrflag;
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 150
#endif
#ifndef YYSTYPE
#define YYSTYPE int
#endif
YYSTYPE yylval, yyval;
typedef int yytabelem;
# define YYERRCODE 256

# line 262 "pdbParse.y"


#include "pdbLex.c"

static char *tokenStr(num)
int num;
{
	static struct {
		int num;
		char *str;
	 } tokstrs[] = {
	DOUBLE,		"double",
	STRING,		"string",
	INTEGER,	"integer",
	IDENTIFIER,	"identifier",
	LEFTPAREN,	"(",
	RIGHTPAREN,	")",
	LEFTANGLE,	"<",
	RIGHTANGLE,	">",
	EQUAL,		"=",
	COMMA,		",", 
        QUESTION_MARK,  "?",
	COLON,		":",
	};
	int k;

	for (k=0; k<ARRAY_SIZE(tokstrs); k++)
	 { if (num == tokstrs[k].num)
	    { return (tokstrs[k].str);
	    }
	 }
	return ("???");
}

PdbSet *pdbParse (fp)
FILE *fp;
{
	hashTabCreate (1021, (int(*)())0);
	yylexinit(fp);
	errMsgSet = 0;
	if (yyparse())
	 { if (errMsgSet)
	    { printf ("%s", errMsgBuf);
	    }
	   else
	    { printf ("parse error\n");
	    }
	   hashTabFree ();
	   return (0);
	 }
	else
	 { hashTabFree ();
	   return (rootSet);
	 }

}

static printParName(p)
PdbPar *p;
{
	printf (" %s%s", (p->name?p->name:""),
			 (p->flags&PDB_DECLARED ? "=" : p->flags ? ":" : ""));
}

pdbPrintSet (set)
PdbSet *set;
{
	PdbPar *p;

	printf ("BEGIN SET code=0x%x len=%d\n", set->code, set->len);
	for (p=set->list; p; p=p->next)
	 { switch (p->type)
	    { case PDB_NONE:
	       { printf ("NONE\n");
		 break;
	       }
	      case PDB_INTEGER:
	       { printf ("INTEGER");
		 printParName(p);
		 printf ("%d\n", p->val.i);
		 break;
	       }
	      case PDB_DOUBLE:
	       { printf ("DOUBLE");
		 printParName(p);
		 printf ("%g\n", p->val.d);
		 break;
	       }
	      case PDB_STRING:
	       { printf ("STRING");
		 printParName(p);
		 printf ("%s\n", p->val.s);
		 break;
	       }
	      case PDB_SET:
	       { printf ("SET");
		 printParName(p);
		 printf ("\n");
		 pdbPrintSet (p->val.set);
		 break;
	       }
	    }
	 }
	printf ("END SET\n");
}

binop (p1, p2, op)
register PdbPar *p1, *p2;
char op;
{
	double val1, val2;

	if ((p1->type != PDB_INTEGER && p1->type != PDB_DOUBLE) ||
	    (p2->type != PDB_INTEGER && p2->type != PDB_DOUBLE))
	 { sprintf (errMsgBuf,
"line %d: only numeric expressions are permitted\n", p1->lineno);
	   errMsgSet = 1;
	   return (-1);
	 }
	if (p1->type == PDB_INTEGER && p2->type == PDB_INTEGER)
	 { switch (op)
	    { case '+':
	       { p1->val.i = p1->val.i + p2->val.i;
		 break;
	       }
	      case '-':
	       { p1->val.i = p1->val.i - p2->val.i;
		 break;
	       }
	      case '*':
	       { p1->val.i = p1->val.i * p2->val.i;
		 break;
	       }
	      case '/':
	       { if (p2->val.i == 0)
		  { sprintf (errMsgBuf,
"line %d: expression divide by zero\n", p2->lineno);
		    errMsgSet = 1;
		    return (-1);
		  }
		 p1->val.i = p1->val.i / p2->val.i;
		 break;
	       }
	    }
	 }
	else
	 { val1 = (p1->type == PDB_INTEGER ? p1->val.i : p1->val.d);
	   val2 = (p1->type == PDB_INTEGER ? p2->val.i : p2->val.d);
	   switch (op)
	    { case '+':
	       { p1->val.d = val1 + val2;
		 break;
	       }
	      case '-':
	       { p1->val.d = val1 - val2;
		 break;
	       }
	      case '*':
	       { p1->val.d = val1 * val2;
		 break;
	       }
	      case '/':
	       { if (val2 == 0.0)
		  { sprintf (errMsgBuf,
"line %d: expression divide by zero\n", p2->lineno);
		    errMsgSet = 1;
		    return (-1);
		  }
		 p1->val.d = val1 / val2;
		 break;
	       }
	    }
	   p1->type = PDB_DOUBLE;
	 }
	return (1);
}

unnop (p1, op)
register PdbPar *p1;
char op;
{
	if (p1->type != PDB_INTEGER && p1->type != PDB_DOUBLE)
	 { sprintf (errMsgBuf,
"line %d: only numeric expressions are permitted\n", p1->lineno);
	   errMsgSet = 1;
	   return (-1);
	 }
	if (p1->type == PDB_INTEGER)
	 { switch (op)
	    { case '-':
	       { p1->val.i = -p1->val.i;
		 break;
	       }
	    }
	 }
	else
	 { switch (op)
	    { case '-':
	       { p1->val.d = -p1->val.d;
		 break;
	       }
	    }
	 }
	return (1);
}

#if TEST

char **argvec;

main(argc, argv)
int argc;
char **argv;
{
	FILE *fp;
	char *fileName = NULL;
	int verbose = 0;

	argvec = argv;
	argc--; argv++;
	while (argc > 0)
	 { 
	   if (!fileName)
	    { fileName = *argv;
	    }
	   else if (ARGUMENT("-v"))
	    { verbose = 1;
	    }
	   else
	    { goto usage;
	    }
	   argc--; argv++;
	   continue;
usage:
	   fprintf (stderr, "Usage: %s [<file>] [-v]\n", argvec[0]);
	   exit (-1);
	 }

	if ((fp = fopen(fileName,"r")) == NULL)
	 { printf ("can't open file %s\n", fileName);
	 }

	if (pdbParse(fp))
	 { if (verbose)
	    { pdbPrintSet (rootSet);
	    }
	 }

	exit (0);
}

#endif
yytabelem yyexca[] ={
-1, 1,
	0, -1,
	-2, 0,
	};
# define YYNPROD 24
# define YYLAST 59
yytabelem yyact[]={

     8,    10,     9,     6,    15,    23,    13,    37,    36,     5,
     4,    21,    22,    11,    14,     8,    10,     9,     6,    15,
     3,    13,     1,     2,     5,     4,     0,    12,     0,    14,
     8,    10,     9,    25,    15,     7,    13,    19,    20,    21,
    22,     0,    17,    26,    14,    18,    16,    35,     0,     0,
    24,    27,    28,    29,    30,    31,    32,    33,    34 };
yytabelem yypact[]={

 -1000, -1000,  -242, -1000, -1000, -1000,  -223,  -233, -1000, -1000,
 -1000, -1000, -1000, -1000,  -227,  -227,  -227,  -227,  -227,  -227,
  -227,  -227,  -227, -1000,  -261, -1000,  -254,  -233,  -233,  -233,
  -233,  -261,  -261, -1000, -1000,  -257, -1000, -1000 };
yytabelem yypgo[]={

     0,    22,    23,    20,    35,    13,    27,     5 };
yytabelem yyr1[]={

     0,     1,     2,     2,     2,     2,     2,     3,     3,     3,
     4,     4,     4,     4,     4,     4,     6,     6,     6,     6,
     6,     6,     7,     5 };
yytabelem yyr2[]={

     0,     3,     1,     5,     5,     5,     9,     7,     7,     3,
     3,     3,     3,     3,     3,     3,     7,     7,     7,     7,
     5,     7,     1,     9 };
yytabelem yychk[]={

 -1000,    -1,    -2,    -3,   267,   266,   260,    -4,   257,   259,
   258,    -5,    -6,   263,   271,   261,   269,   265,   268,   270,
   271,   272,   273,    -7,    -4,   260,    -6,    -4,    -4,    -4,
    -4,    -4,    -4,    -4,    -4,    -2,   262,   264 };
yytabelem yydef[]={

     2,    -2,     1,     3,     4,     5,    14,     9,    10,    11,
    12,    13,    15,    22,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     2,    20,    14,    15,     0,     6,     7,
     8,    16,    17,    18,    19,     0,    21,    23 };
typedef struct { char *t_name; int t_val; } yytoktype;
#ifndef YYDEBUG
#	define YYDEBUG	0	/* don't allow debugging */
#endif

#if YYDEBUG

yytoktype yytoks[] =
{
	"DOUBLE",	257,
	"STRING",	258,
	"INTEGER",	259,
	"IDENTIFIER",	260,
	"LEFTPAREN",	261,
	"RIGHTPAREN",	262,
	"LEFTANGLE",	263,
	"RIGHTANGLE",	264,
	"EQUAL",	265,
	"COMMA",	266,
	"QUESTION_MARK",	267,
	"COLON",	268,
	"ASSIGN",	269,
	"PLUS",	270,
	"MINUS",	271,
	"TIMES",	272,
	"DIVIDE",	273,
	"ERR",	274,
	"-unknown-",	-1	/* ends search */
};

char * yyreds[] =
{
	"-no such reduction-",
	"file : paramList",
	"paramList : /* empty */",
	"paramList : paramList paramSpec",
	"paramList : paramList QUESTION_MARK",
	"paramList : paramList COMMA",
	"paramList : paramList IDENTIFIER ASSIGN param",
	"paramSpec : IDENTIFIER EQUAL param",
	"paramSpec : IDENTIFIER COLON param",
	"paramSpec : param",
	"param : DOUBLE",
	"param : INTEGER",
	"param : STRING",
	"param : paramSet",
	"param : IDENTIFIER",
	"param : expr",
	"expr : param PLUS param",
	"expr : param MINUS param",
	"expr : param TIMES param",
	"expr : param DIVIDE param",
	"expr : MINUS param",
	"expr : LEFTPAREN expr RIGHTPAREN",
	"paramSet : LEFTANGLE",
	"paramSet : LEFTANGLE paramList RIGHTANGLE",
};
#endif /* YYDEBUG */
/* 
 *	Copyright 1987 Silicon Graphics, Inc. - All Rights Reserved
 */

/* #ident	"@(#)yacc:yaccpar	1.10" */
#ident	"$Revision: 1.5 $"

/*
** Skeleton parser driver for yacc output
*/

/*
** yacc user known macros and defines
*/
#define YYERROR		goto yyerrlab
#define YYACCEPT	return(0)
#define YYABORT		return(1)
#define YYBACKUP( newtoken, newvalue )\
{\
	if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\
	{\
		yyerror( "syntax error - cannot backup" );\
		goto yyerrlab;\
	}\
	yychar = newtoken;\
	yystate = *yyps;\
	yylval = newvalue;\
	goto yynewstate;\
}
#define YYRECOVERING()	(!!yyerrflag)
#ifndef YYDEBUG
#	define YYDEBUG	1	/* make debugging available */
#endif

/*
** user known globals
*/
int yydebug;			/* set to 1 to get debugging */

/*
** driver internal defines
*/
#define YYFLAG		(-1000)

/*
** global variables used by the parser
*/
YYSTYPE yyv[ YYMAXDEPTH ];	/* value stack */
int yys[ YYMAXDEPTH ];		/* state stack */

YYSTYPE *yypv;			/* top of value stack */
int *yyps;			/* top of state stack */

int yystate;			/* current state */
int yytmp;			/* extra var (lasts between blocks) */

int yynerrs;			/* number of errors */
int yyerrflag;			/* error recovery flag */
int yychar;			/* current input token number */



/*
** yyparse - return 0 if worked, 1 if syntax error not recovered from
*/
int
yyparse()
{
	register YYSTYPE *yypvt;	/* top of value stack for $vars */

	/*
	** Initialize externals - yyparse may be called more than once
	*/
	yypv = &yyv[-1];
	yyps = &yys[-1];
	yystate = 0;
	yytmp = 0;
	yynerrs = 0;
	yyerrflag = 0;
	yychar = -1;

	goto yystack;
	{
		register YYSTYPE *yy_pv;	/* top of value stack */
		register int *yy_ps;		/* top of state stack */
		register int yy_state;		/* current state */
		register int  yy_n;		/* internal state number info */

		/*
		** get globals into registers.
		** branch to here only if YYBACKUP was called.
		*/
	yynewstate:
		yy_pv = yypv;
		yy_ps = yyps;
		yy_state = yystate;
		goto yy_newstate;

		/*
		** get globals into registers.
		** either we just started, or we just finished a reduction
		*/
	yystack:
		yy_pv = yypv;
		yy_ps = yyps;
		yy_state = yystate;

		/*
		** top of for (;;) loop while no reductions done
		*/
	yy_stack:
		/*
		** put a state and value onto the stacks
		*/
#if YYDEBUG
		/*
		** if debugging, look up token value in list of value vs.
		** name pairs.  0 and negative (-1) are special values.
		** Note: linear search is used since time is not a real
		** consideration while debugging.
		*/
		if ( yydebug )
		{
			register int yy_i;

			printf( "State %d, token ", yy_state );
			if ( yychar == 0 )
				printf( "end-of-file\n" );
			else if ( yychar < 0 )
				printf( "-none-\n" );
			else
			{
				for ( yy_i = 0; yytoks[yy_i].t_val >= 0;
					yy_i++ )
				{
					if ( yytoks[yy_i].t_val == yychar )
						break;
				}
				printf( "%s\n", yytoks[yy_i].t_name );
			}
		}
#endif /* YYDEBUG */
		if ( ++yy_ps >= &yys[ YYMAXDEPTH ] )	/* room on stack? */
		{
			yyerror( "yacc stack overflow" );
			YYABORT;
		}
		*yy_ps = yy_state;
		*++yy_pv = yyval;

		/*
		** we have a new state - find out what to do
		*/
	yy_newstate:
		if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG )
			goto yydefault;		/* simple state */
#if YYDEBUG
		/*
		** if debugging, need to mark whether new token grabbed
		*/
		yytmp = yychar < 0;
#endif
		if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) )
			yychar = 0;		/* reached EOF */
#if YYDEBUG
		if ( yydebug && yytmp )
		{
			register int yy_i;

			printf( "Received token " );
			if ( yychar == 0 )
				printf( "end-of-file\n" );
			else if ( yychar < 0 )
				printf( "-none-\n" );
			else
			{
				for ( yy_i = 0; yytoks[yy_i].t_val >= 0;
					yy_i++ )
				{
					if ( yytoks[yy_i].t_val == yychar )
						break;
				}
				printf( "%s\n", yytoks[yy_i].t_name );
			}
		}
#endif /* YYDEBUG */
		if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) )
			goto yydefault;
		if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar )	/*valid shift*/
		{
			yychar = -1;
			yyval = yylval;
			yy_state = yy_n;
			if ( yyerrflag > 0 )
				yyerrflag--;
			goto yy_stack;
		}

	yydefault:
		if ( ( yy_n = yydef[ yy_state ] ) == -2 )
		{
#if YYDEBUG
			yytmp = yychar < 0;
#endif
			if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) )
				yychar = 0;		/* reached EOF */
#if YYDEBUG
			if ( yydebug && yytmp )
			{
				register int yy_i;

				printf( "Received token " );
				if ( yychar == 0 )
					printf( "end-of-file\n" );
				else if ( yychar < 0 )
					printf( "-none-\n" );
				else
				{
					for ( yy_i = 0;
						yytoks[yy_i].t_val >= 0;
						yy_i++ )
					{
						if ( yytoks[yy_i].t_val
							== yychar )
						{
							break;
						}
					}
					printf( "%s\n", yytoks[yy_i].t_name );
				}
			}
#endif /* YYDEBUG */
			/*
			** look through exception table
			*/
			{
				register int *yyxi = yyexca;

				while ( ( *yyxi != -1 ) ||
					( yyxi[1] != yy_state ) )
				{
					yyxi += 2;
				}
				while ( ( *(yyxi += 2) >= 0 ) &&
					( *yyxi != yychar ) )
					;
				if ( ( yy_n = yyxi[1] ) < 0 )
					YYACCEPT;
			}
		}

		/*
		** check for syntax error
		*/
		if ( yy_n == 0 )	/* have an error */
		{
			/* no worry about speed here! */
			switch ( yyerrflag )
			{
			case 0:		/* new error */
				yyerror( "syntax error" );
				goto skip_init;
			yyerrlab:
				/*
				** get globals into registers.
				** we have a user generated syntax type error
				*/
				yy_pv = yypv;
				yy_ps = yyps;
				yy_state = yystate;
				yynerrs++;
			skip_init:
			case 1:
			case 2:		/* incompletely recovered error */
					/* try again... */
				yyerrflag = 3;
				/*
				** find state where "error" is a legal
				** shift action
				*/
				while ( yy_ps >= yys )
				{
					yy_n = yypact[ *yy_ps ] + YYERRCODE;
					if ( yy_n >= 0 && yy_n < YYLAST &&
						yychk[yyact[yy_n]] == YYERRCODE)					{
						/*
						** simulate shift of "error"
						*/
						yy_state = yyact[ yy_n ];
						goto yy_stack;
					}
					/*
					** current state has no shift on
					** "error", pop stack
					*/
#if YYDEBUG
#	define _POP_ "Error recovery pops state %d, uncovers state %d\n"
					if ( yydebug )
						printf( _POP_, *yy_ps,
							yy_ps[-1] );
#	undef _POP_
#endif
					yy_ps--;
					yy_pv--;
				}
				/*
				** there is no state on stack with "error" as
				** a valid shift.  give up.
				*/
				YYABORT;
			case 3:		/* no shift yet; eat a token */
#if YYDEBUG
				/*
				** if debugging, look up token in list of
				** pairs.  0 and negative shouldn't occur,
				** but since timing doesn't matter when
				** debugging, it doesn't hurt to leave the
				** tests here.
				*/
				if ( yydebug )
				{
					register int yy_i;

					printf( "Error recovery discards " );
					if ( yychar == 0 )
						printf( "token end-of-file\n" );
					else if ( yychar < 0 )
						printf( "token -none-\n" );
					else
					{
						for ( yy_i = 0;
							yytoks[yy_i].t_val >= 0;
							yy_i++ )
						{
							if ( yytoks[yy_i].t_val
								== yychar )
							{
								break;
							}
						}
						printf( "token %s\n",
							yytoks[yy_i].t_name );
					}
				}
#endif /* YYDEBUG */
				if ( yychar == 0 )	/* reached EOF. quit */
					YYABORT;
				yychar = -1;
				goto yy_newstate;
			}
		}/* end if ( yy_n == 0 ) */
		/*
		** reduction by production yy_n
		** put stack tops, etc. so things right after switch
		*/
#if YYDEBUG
		/*
		** if debugging, print the string that is the user's
		** specification of the reduction which is just about
		** to be done.
		*/
		if ( yydebug )
			printf( "Reduce by (%d) \"%s\"\n",
				yy_n, yyreds[ yy_n ] );
#endif
		yytmp = yy_n;			/* value to switch over */
		yypvt = yy_pv;			/* $vars top of value stack */
		/*
		** Look in goto table for next state
		** Sorry about using yy_state here as temporary
		** register variable, but why not, if it works...
		** If yyr2[ yy_n ] doesn't have the low order bit
		** set, then there is no action to be done for
		** this reduction.  So, no saving & unsaving of
		** registers done.  The only difference between the
		** code just after the if and the body of the if is
		** the goto yy_stack in the body.  This way the test
		** can be made before the choice of what to do is needed.
		*/
		{
			/* length of production doubled with extra bit */
			register int yy_len = yyr2[ yy_n ];

			if ( !( yy_len & 01 ) )
			{
				yy_len >>= 1;
				yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
				yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
					*( yy_ps -= yy_len ) + 1;
				if ( yy_state >= YYLAST ||
					yychk[ yy_state =
					yyact[ yy_state ] ] != -yy_n )
				{
					yy_state = yyact[ yypgo[ yy_n ] ];
				}
				goto yy_stack;
			}
			yy_len >>= 1;
			yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
			yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
				*( yy_ps -= yy_len ) + 1;
			if ( yy_state >= YYLAST ||
				yychk[ yy_state = yyact[ yy_state ] ] != -yy_n )
			{
				yy_state = yyact[ yypgo[ yy_n ] ];
			}
		}
					/* save until reenter driver code */
		yystate = yy_state;
		yyps = yy_ps;
		yypv = yy_pv;
	}
	/*
	** code supplied by user is placed in this switch
	*/
	switch( yytmp )
	{
		
case 1:
# line 96 "pdbParse.y"
{ rootSet = yypvt[-0].set;
		   } break;
case 2:
# line 100 "pdbParse.y"
{ yyval.set = (PdbSet*)calloc(1,sizeof(PdbSet));
		     yyval.previousComma = 1;
		   } break;
case 3:
# line 104 "pdbParse.y"
{ yyval.set = yypvt[-1].set;
		     yyval.par = yypvt[-0].par;
		     if (yyval.set->len++ == 0)
		      { yyval.set->list = yypvt[-0].par;
		      }
		     else
		      { yypvt[-1].par->next = yypvt[-0].par;
		      }
		     yyval.set->code |= yypvt[-0].par->type;
		     yyval.previousComma = 0;
		   } break;
case 4:
# line 116 "pdbParse.y"
{ PdbPar *par;
		     par = (PdbPar*)calloc(1,sizeof(PdbPar));
	             yyval.set = yypvt[-1].set;
		     yyval.par = yypvt[-0].par;
		     if (yyval.set->len++ == 0)
		      { yyval.set->list = par;
		      }
		     else
		      { yypvt[-1].par->next = par;
		      }
		     yyval.par = par;
		     yyval.par->lineno = yypvt[-0].lineno;
		     yyval.previousComma = 0;
		   } break;
case 5:
# line 131 "pdbParse.y"
{ yyval.set = yypvt[-1].set;
		     if (yypvt[-1].previousComma)
		      { PdbPar *par;
			par = (PdbPar*)calloc(1,sizeof(PdbPar));
			if (yyval.set->len++ == 0)
			 { yyval.set->list = par;
			 }
			else
			 { yypvt[-1].par->next = par;
			 }			
			yyval.par = par;
			yyval.par->lineno = yypvt[-0].lineno;
		      }
		     else
		      { yyval.par = yypvt[-1].par;
		      }
		     yyval.previousComma = 1;
		   } break;
case 6:
# line 150 "pdbParse.y"
{ void *old;
		     hashInsert (yypvt[-2].u.s, (void*)yypvt[-0].par, /*clobber=*/1, &old);
		     if (old)
		      { free ((char*)old);
		      }
		     yyval = yypvt[-3];
		   } break;
case 7:
# line 159 "pdbParse.y"
{ yyval.par = yypvt[-0].par;
		     yyval.par->name = yypvt[-2].u.s;
		     yyval.par->lineno = yypvt[-2].lineno;
		     yyval.par->flags |= PDB_DECLARED;
		   } break;
case 8:
# line 165 "pdbParse.y"
{ if (yypvt[-0].par->type == PDB_SET)
		      { yyval.par = yypvt[-0].par;
			yyval.par->name = yypvt[-2].u.s;
			yyval.par->lineno = yypvt[-2].lineno;
			yyval.par->flags |= PDB_CONSTRUCTED;
		      }
		     else
		      { sprintf(errMsgBuf,
"line %d: ':' operator must be followed by a set\n", yypvt[-2].lineno);
			errMsgSet = 1;
			YYERROR;
		      }
		   } break;
case 9:
# line 179 "pdbParse.y"
{ yyval.par = yypvt[-0].par;
		   } break;
case 10:
# line 183 "pdbParse.y"
{ yyval.par = (PdbPar*)calloc(1,sizeof(PdbPar));
		     yyval.par->type = PDB_DOUBLE;
		     yyval.par->val.d = yypvt[-0].u.d;
		     yyval.par->lineno = yypvt[-0].lineno;
		   } break;
case 11:
# line 189 "pdbParse.y"
{ yyval.par = (PdbPar*)calloc(1,sizeof(PdbPar));
		     yyval.par->type = PDB_INTEGER;
		     yyval.par->val.i = yypvt[-0].u.i;
		     yyval.par->lineno = yypvt[-0].lineno;
		   } break;
case 12:
# line 195 "pdbParse.y"
{ yyval.par = (PdbPar*)calloc(1,sizeof(PdbPar));
		     yyval.par->type = PDB_STRING;
		     yyval.par->val.s = yypvt[-0].u.s;
		     yyval.par->lineno = yypvt[-0].lineno;
		   } break;
case 13:
# line 201 "pdbParse.y"
{ yyval.par = (PdbPar*)calloc(1,sizeof(PdbPar));
		     yyval.par->type = PDB_SET;
		     yyval.par->val.set = yypvt[-0].set;
		     yyval.par->lineno = yypvt[-0].lineno;
		   } break;
case 14:
# line 207 "pdbParse.y"
{ PdbPar *p;	
		     if (p = (PdbPar*)hashFind(yypvt[-0].u.s))
		      { yyval.par = (PdbPar*)calloc(1,sizeof(PdbPar));
			(*yyval.par) = *p;
			yyval.par->lineno = yypvt[-0].lineno;
		      }
		     else
		      { sprintf(errMsgBuf,
"line %d: variable '%s' not defined\n", yypvt[-0].lineno, yypvt[-0].u.s);
			errMsgSet = 1;
			YYERROR;
		      }
		   } break;
case 15:
# line 221 "pdbParse.y"
{ yyval.par = yypvt[-0].par;
		   } break;
case 16:
# line 224 "pdbParse.y"
{ if (binop (yypvt[-2].par, yypvt[-0].par, '+') < 0)
		      { YYERROR;
		      }
		     yyval.par = yypvt[-2].par;
		   } break;
case 17:
# line 230 "pdbParse.y"
{ if (binop (yypvt[-2].par, yypvt[-0].par, '-') < 0)
		      { YYERROR;
		      }
		     yyval.par = yypvt[-2].par;
		   } break;
case 18:
# line 236 "pdbParse.y"
{ if (binop (yypvt[-2].par, yypvt[-0].par, '*') < 0)
		      { YYERROR;
		      }
		     yyval.par = yypvt[-2].par;
		   } break;
case 19:
# line 242 "pdbParse.y"
{ if (binop (yypvt[-2].par, yypvt[-0].par, '/') < 0)
		      { YYERROR;
		      }
		     yyval.par = yypvt[-2].par;
		   } break;
case 20:
# line 248 "pdbParse.y"
{ if (unnop (yypvt[-0].par, '-') < 0)
		      { YYERROR;
		      }
		     yyval.par = yypvt[-0].par;
		   } break;
case 21:
# line 254 "pdbParse.y"
{ yyval.par = yypvt[-1].par;
		   } break;
case 22:
# line 256 "pdbParse.y"
{ hashPushLevel(); } break;
case 23:
# line 257 "pdbParse.y"
{ yyval.set = yypvt[-1].set;
		     hashPopLevel();
		   } break;
	}
	goto yystack;		/* reset registers in driver code */
}
