xref: /csrg-svn/usr.bin/pascal/eyacc/ey2.c (revision 62087)
147968Sbostic /*-
2*62087Sbostic  * Copyright (c) 1979, 1993
3*62087Sbostic  *	The Regents of the University of California.  All rights reserved.
447968Sbostic  *
547968Sbostic  * %sccs.include.proprietary.c%
619571Smckusick  */
719571Smckusick 
819571Smckusick #ifndef lint
9*62087Sbostic static char sccsid[] = "@(#)ey2.c	8.1 (Berkeley) 06/06/93";
1047968Sbostic #endif /* not lint */
1119571Smckusick 
1219571Smckusick # include "ey.h"
1319571Smckusick # define IDENTIFIER 257
1419571Smckusick # define MARK 258
1519571Smckusick # define TERM 259
1619571Smckusick # define LEFT 260
1719571Smckusick # define BINARY 261
1819571Smckusick # define RIGHT 262
1919571Smckusick # define PREC 263
2019571Smckusick # define LCURLY 264
2119571Smckusick # define C_IDENTIFIER 265  /* name followed by colon */
2219571Smckusick # define NUMBER 266
2319571Smckusick 
2419571Smckusick FILE	*copen();
2519571Smckusick 
setup(argc,argv)2619571Smckusick setup(argc,argv) int argc; char *argv[];
2719571Smckusick {	int i,j,lev,t;
2819571Smckusick 	int c;
2919571Smckusick 
3019571Smckusick 	foutput = stdout;
3119571Smckusick 	i = 1;
3219571Smckusick 	while( argc >= 2  && argv[1][0] == '-' ) {
3319571Smckusick 		while( *++(argv[1]) ){
3419571Smckusick 			switch( *argv[1] ){
3519571Smckusick 			case 'v':
3619571Smckusick 			case 'V':
3719571Smckusick 				foutput = copen("y.output", 'w' );
3819571Smckusick 				if( foutput == 0 ) error( "cannot open y.output");
3919571Smckusick 				continue;
4019571Smckusick 			case 'o':
4119571Smckusick 			case 'O':
4219571Smckusick 				oflag = 1;
4319571Smckusick 				continue;
4419571Smckusick 			case 'r':
4519571Smckusick 			case 'R':
4619571Smckusick 				oflag = 1;
4719571Smckusick 				rflag = 1;
4819571Smckusick 				continue;
4919571Smckusick 			default:  error( "illegal option: %c", *argv[1]);
5019571Smckusick 				}
5119571Smckusick 			}
5219571Smckusick 		argv++;
5319571Smckusick 		argc--;
5419571Smckusick 		}
5519571Smckusick 
5619571Smckusick 	ftable = copen( oflag ? "yacc.tmp" : "y.tab.c" , 'w' );
5719571Smckusick 	if( ftable==0 ) error( "cannot open table file" );
5819571Smckusick 	if( argc > 1 ) { cin = copen( argv[1], 'r' );
5919571Smckusick 	if( cin == 0 ) error( "cannot open input" );
6019571Smckusick 	}
6119571Smckusick 	settab();
6219571Smckusick 	fprintf( cout , "#\n");
6319571Smckusick 	ctokn = "$end";
6419571Smckusick 	defin(0);  /* eof */
6519571Smckusick 	extval = 0400;  /* beginning of assigned values */
6619571Smckusick 	ctokn = "error";
6719571Smckusick 	defin(0);
6819571Smckusick 	ctokn = "$accept";
6919571Smckusick 	defin(1);
7019571Smckusick 	mem=mem0;
7119571Smckusick 	cnamp = cnames;
7219571Smckusick 	lev=0;
7319571Smckusick 	i=0;
7419571Smckusick 
7519571Smckusick 	while( ( t = gettok() ) != EOF ) {
7619571Smckusick 		switch( t ){
7719571Smckusick 			case IDENTIFIER:	j = chfind(0);
7819571Smckusick 					trmlev[j] = lev;
7919571Smckusick 					continue;
8019571Smckusick 			case ',':
8119571Smckusick 			case ';':		continue;
8219571Smckusick 			case TERM:		lev=0; continue;
8319571Smckusick 			case LEFT:		lev=(++i<<3)|01; continue;
8419571Smckusick 			case BINARY:	lev=(++i<<3)|02; continue;
8519571Smckusick 			case RIGHT:	lev=(++i<<3)|03; continue;
8619571Smckusick 			case MARK:
8719571Smckusick 					defout();
8819571Smckusick 					if( rflag ){ /* RATFOR */
8919571Smckusick 						fprintf( cout ,  "define yyerrok yyerrf = 0\n" );
9019571Smckusick 						fprintf( cout ,  "define yyclearin yychar = -1\n" );
9119571Smckusick 						fprintf( cout ,  "subroutine yyactr(yyprdn)\n");
9219571Smckusick 						fprintf( cout ,  "common/yycomn/yylval,yyval,yypv,yyvalv(150)\n" );
9319571Smckusick 						fprintf( cout ,  "common/yylcom/yychar,yyerrf,yydebu\n" );
9419571Smckusick 						fprintf( cout ,  "integer yychar, yyerrf, yydebu\n" );
9519571Smckusick 						fprintf( cout ,  "integer yyprdn,yyval,yylval,yypv,yyvalv\n" );
9619571Smckusick 						}
9719571Smckusick 					else {
9819571Smckusick 						fprintf( cout ,  "#define yyclearin yychar = -1\n" );
9919571Smckusick 						fprintf( cout ,  "#define yyerrok yyerrflag = 0\n" );
10019571Smckusick 						fprintf( cout ,  "extern int yychar, yyerrflag;\n" );
10119571Smckusick 						fprintf( cout , "\nint yyval 0;\nint *yypv;\nint yylval 0;");
10219571Smckusick 						fprintf( cout , "\nyyactr(__np__){\n");
10319571Smckusick 						}
10419571Smckusick 					break;
10519571Smckusick 			case LCURLY:	defout();
10619571Smckusick 					cpycode();
10719571Smckusick 					continue;
10819571Smckusick 			case NUMBER:
10919571Smckusick 				trmset[j].value = numbval;
11019571Smckusick 				if( j < ndefout && j>2 )
11119571Smckusick 					error("please define type # of %s earlier", trmset[j].name );
11219571Smckusick 				continue;
11319571Smckusick 			default:	error("bad precedence syntax, input %d", t );
11419571Smckusick 			}
11519571Smckusick 		break;
11619571Smckusick 		}
11719571Smckusick 	prdptr[0]=mem;
11819571Smckusick 	/* added production */
11919571Smckusick 	*mem++ = NTBASE;
12019571Smckusick 	*mem++ = NTBASE+1;
12119571Smckusick 	*mem++ = 1;
12219571Smckusick 	*mem++ = 0;
12319571Smckusick 	prdptr[1]=mem;
12419571Smckusick 	i=0;
12519571Smckusick 
12619571Smckusick 	/* i is 0 when a rule can begin, 1 otherwise */
12719571Smckusick 
12819571Smckusick 	for(;;) switch( t=gettok() ) {
12919571Smckusick 	case C_IDENTIFIER:		if( mem == prdptr[1] ) {  /* first time */
13019571Smckusick 						if( rflag ){
13119571Smckusick 							fprintf( cout ,  "goto 1000\n" );
13219571Smckusick 							}
13319571Smckusick 						else fprintf( cout , "\nswitch(__np__){\n");
13419571Smckusick 						}
13519571Smckusick 				if( i != 0 ) error( "previous rule not terminated" );
13619571Smckusick 				*mem = chfind(1);
13719571Smckusick 				if( *mem < NTBASE )error( "token illegal on lhs of grammar rule" );
13819571Smckusick 				i=1;
13919571Smckusick 				++mem;
14019571Smckusick 				continue;
14119571Smckusick 	case IDENTIFIER:
14219571Smckusick 			*mem=chfind(1);
14319571Smckusick 			if(*mem < NTBASE)levprd[nprod]=trmlev[*mem];
14419571Smckusick 			mem++;
14519571Smckusick 			if(i==0) error("missing :");
14619571Smckusick 			continue;
14719571Smckusick 	case '=':		levprd[nprod] |= 04;
14819571Smckusick 				if( i==0 ) error("semicolon preceeds action");
14919571Smckusick 			fprintf( cout ,  rflag?"\n%d ":"\ncase %d:", nprod );
15019571Smckusick 			cpyact();
15119571Smckusick 			fprintf( cout ,  rflag ? " return" : " break;" );
15219571Smckusick 	case '|':
15319571Smckusick 	case ';':		if(i){
15419571Smckusick 				*mem++ = -nprod;
15519571Smckusick 				prdptr[++nprod] = mem;
15619571Smckusick 				levprd[nprod]=0;
15719571Smckusick 				i=0;}
15819571Smckusick 			if (t=='|'){i=1;*mem++ = *prdptr[nprod-1];}
15919571Smckusick 			continue;
16019571Smckusick 	case 0:		/* End Of File */
16119571Smckusick 	case EOF:
16219571Smckusick 	case MARK:	if( i != 0 ) error( "rule not terminated before %%%% or EOF" );
16319571Smckusick 			settab();
16419571Smckusick 			finact();
16519571Smckusick 			/* copy the programs which follow the rules */
16619571Smckusick 			if( t == MARK ){
16719571Smckusick 				while (( c=fgetc( cin)) != EOF ) fputc(c,cout);
16819571Smckusick 				}
16919571Smckusick 			return;
17019571Smckusick 	case PREC:
17119571Smckusick 		if( i==0 ) error( "%%prec must appear inside rule" );
17219571Smckusick 		if( gettok()!=IDENTIFIER)error("illegal %%prec syntax" );
17319571Smckusick 		j=chfind(2);
17419571Smckusick 		if(j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name);
17519571Smckusick 		levprd[nprod]=trmlev[j];
17619571Smckusick 		continue;
17719571Smckusick 	case LCURLY:
17819571Smckusick 		if( i!=0 ) error( "%%{ appears within a rule" );
17919571Smckusick 		cpycode();
18019571Smckusick 		continue;
18119571Smckusick 	default: error( "syntax error, input %d", t  );
18219571Smckusick 	}
18319571Smckusick }
18419571Smckusick 
finact()18519571Smckusick finact(){
18619571Smckusick 	/* finish action routine */
18719571Smckusick 	register i;
18819571Smckusick 
18919571Smckusick 	if( rflag ){
19019571Smckusick 
19119571Smckusick 		fprintf( cout ,  "\n1000 goto(" );
19219571Smckusick 		for( i=1; i<nprod; ++i ){
19319571Smckusick 			fprintf( cout ,  "%d,", (levprd[i]&04)==0?999:i );
19419571Smckusick 			}
19519571Smckusick 		fprintf( cout ,  "999),yyprdn\n" );
19619571Smckusick 		fprintf( cout ,  "999 return\nend\n" );
19719571Smckusick 		fprintf( cout ,  "define YYERRCODE %d\n", trmset[2].value );
19819571Smckusick 		}
19919571Smckusick 	else {
20019571Smckusick 		fprintf( cout ,  "\n}\n}\n" );
20119571Smckusick 		fprintf( cout ,  "int yyerrval %d;\n", trmset[2].value );
20219571Smckusick 		}
20319571Smckusick 	}
defin(t)20419571Smckusick defin(t) {
20519571Smckusick /*	define ctokn to be a terminal if t=0
20619571Smckusick 	or a nonterminal if t=1		*/
20719571Smckusick 	char *cp,*p;
20819571Smckusick 	int c;
20919571Smckusick 
21019571Smckusick 
21119571Smckusick         if (t) {
21219571Smckusick           if( ++nnonter >= ntlim ) error("too many nonterminals, limit %d",ntlim);
21319571Smckusick 	  nontrst[nnonter].name = ctokn;
21419571Smckusick 	  return( NTBASE + nnonter );
21519571Smckusick           }
21619571Smckusick         else {
21719571Smckusick           if( ++nterms >= tlim ) error("too many terminals, limit %d",tlim );
21819571Smckusick           trmset[nterms].name = ctokn;
21919571Smckusick 	if( ctokn[0]==' ' && ctokn[2]=='\0' ) /* single character literal */
22019571Smckusick 		trmset[nterms].value = ctokn[1];
22119571Smckusick 	else if ( ctokn[0]==' ' && ctokn[1]=='\\' ) { /* escape sequence */
22219571Smckusick 		if( ctokn[3] == '\0' ){ /* single character escape sequence */
22319571Smckusick 			switch ( ctokn[2] ){
22419571Smckusick 				 /* character which is escaped */
22519571Smckusick 			case 'n': trmset[nterms].value = '\n'; break;
22619571Smckusick 			case 'r': trmset[nterms].value = '\r'; break;
22719571Smckusick 			case 'b': trmset[nterms].value = '\b'; break;
22819571Smckusick 			case 't': trmset[nterms].value = '\t'; break;
22919571Smckusick 			case '\'': trmset[nterms].value = '\''; break;
23019571Smckusick 			case '"': trmset[nterms].value = '"'; break;
23119571Smckusick 			case '\\': trmset[nterms].value = '\\'; break;
23219571Smckusick 			default: error( "invalid escape" );
23319571Smckusick 				}
23419571Smckusick 			}
23519571Smckusick 		else if( ctokn[2] <= '7' && ctokn[2]>='0' ){ /* \nnn sequence */
23619571Smckusick 			if( ctokn[3]<'0' || ctokn[3] > '7' || ctokn[4]<'0' ||
23719571Smckusick 				ctokn[4]>'7' || ctokn[5] != '\0' ) error("illegal \\nnn construction" );
23819571Smckusick 			trmset[nterms].value = 64*(ctokn[2]-'0')+8*(ctokn[3]-'0')+ctokn[4]-'0';
23919571Smckusick 			if( trmset[nterms].value == 0 ) error( "'\\000' is illegal" );
24019571Smckusick 			}
24119571Smckusick 		}
24219571Smckusick 	else {
24319571Smckusick 		trmset[nterms].value = extval++;
24419571Smckusick 
24519571Smckusick 		}
24619571Smckusick 	trmlev[nterms] = 0;
24719571Smckusick 	return( nterms );
24819571Smckusick           }
24919571Smckusick }
25019571Smckusick 
defout()25119571Smckusick defout(){ /* write out the defines (at the end of the declaration section) */
25219571Smckusick 
25319571Smckusick 	_REGISTER int i, c;
25419571Smckusick 	_REGISTER char *cp;
25519571Smckusick 
25619571Smckusick 	for( i=ndefout; i<=nterms; ++i ){
25719571Smckusick 
25819571Smckusick 		cp = trmset[i].name;
25919571Smckusick 		if( *cp == ' ' ) ++cp;  /* literals */
26019571Smckusick 
26119571Smckusick 		for( ; (c= *cp)!='\0'; ++cp ){
26219571Smckusick 
26319571Smckusick 			if( c>='a' && c<='z' ||
26419571Smckusick 			    c>='A' && c<='Z' ||
26519571Smckusick 			    c>='0' && c<='9' ||
26619571Smckusick 			    c=='_' )  ; /* VOID */
26719571Smckusick 			else goto nodef;
26819571Smckusick 			}
26919571Smckusick 
27019571Smckusick 		/* define it */
27119571Smckusick 
27219571Smckusick 		fprintf( cout ,  "%c define %s %d\n", rflag?' ':'#', trmset[i].name, trmset[i].value );
27319571Smckusick 
27419571Smckusick 	nodef:	;
27519571Smckusick 		}
27619571Smckusick 
27719571Smckusick 	ndefout = nterms+1;
27819571Smckusick 
27919571Smckusick 	}
28019571Smckusick 
chstash(c)28119571Smckusick chstash( c ){
28219571Smckusick   /* put character away into cnames */
28319571Smckusick   if( cnamp >= &cnames[cnamsz] ) error("too many characters in id's and literals" );
28419571Smckusick   else *cnamp++ = c;
28519571Smckusick   }
28619571Smckusick 
gettok()28719571Smckusick int gettok() {
28819571Smckusick 	int j, base;
28919571Smckusick 	static int peekline; /* number of '\n' seen in lookahead */
29019571Smckusick 	auto int c, match, reserve;
29119571Smckusick 
29219571Smckusick begin:
29319571Smckusick 	reserve = 0;
29419571Smckusick         if( peekc>=0 ) {
29519571Smckusick 		c = peekc;
29619571Smckusick 		lineno += peekline;
29719571Smckusick 		peekc = -1;
29819571Smckusick 		peekline = 0;
29919571Smckusick 		}
30019571Smckusick         else c = fgetc( cin);
30119571Smckusick         while( c==' ' || c=='\n' || c=='\t' || c == '\014'){
30219571Smckusick           if( c == '\n' ) ++lineno;
30319571Smckusick           c=fgetc( cin);
30419571Smckusick           }
30519571Smckusick 	if (c=='/')
30619571Smckusick 		{if (fgetc( cin)!='*')error("illegal /");
30719571Smckusick 		c=fgetc( cin);
30819571Smckusick 		while(c != EOF) {
30919571Smckusick 			if( c == '\n' ) ++lineno;
31019571Smckusick 			if (c=='*')
31119571Smckusick 				{if((c=fgetc( cin))=='/')break;}
31219571Smckusick 			else c=fgetc( cin);}
31319571Smckusick 		if (!c) return(0);
31419571Smckusick 		goto begin;}
31519571Smckusick 	j=0;
31619571Smckusick 	switch(c){
31719571Smckusick 	case '"':
31819571Smckusick 	case '\'':	match = c;
31919571Smckusick 			ctokn = cnamp;
32019571Smckusick 			chstash( ' ' );
32119571Smckusick 			while(1){
32219571Smckusick 				c = fgetc( cin);
32319571Smckusick 				if( c == '\n' || c == '\0' )
32419571Smckusick 					error("illegal or missing ' or \"");
32519571Smckusick 				if( c == '\\' ){
32619571Smckusick 					c = fgetc( cin);
32719571Smckusick 					chstash( '\\' );
32819571Smckusick 					}
32919571Smckusick 				else if( c == match ) break;
33019571Smckusick 				chstash( c );
33119571Smckusick 				}
33219571Smckusick 			break;
33319571Smckusick 	case '%':
33419571Smckusick 	case '\\':	switch(c=fgetc( cin))
33519571Smckusick 		{case '0':	return(TERM);
33619571Smckusick 		case '<':	return(LEFT);
33719571Smckusick 		case '2':	return(BINARY);
33819571Smckusick 		case '>':	return(RIGHT);
33919571Smckusick 		case '%':
34019571Smckusick 		case '\\':	return(MARK);
34119571Smckusick 		case '=':	return(PREC);
34219571Smckusick 		case '{':	return(LCURLY);
34319571Smckusick 		default:	reserve = 1;
34419571Smckusick 		}
34519571Smckusick 	default:	if( c >= '0' && c <= '9' ){ /* number */
34619571Smckusick 				numbval = c-'0' ;
34719571Smckusick 				base = (c=='0') ? 8 : 10 ;
34819571Smckusick 				for( c=fgetc( cin); c>='0' && c<='9'; c=fgetc( cin) ){
34919571Smckusick 					numbval = numbval*base + c - '0';
35019571Smckusick 					}
35119571Smckusick 				peekc = c;
35219571Smckusick 				return(NUMBER);
35319571Smckusick 				}
35419571Smckusick 			else if( (c>='a'&&c<='z')||(c>='A'&&c<='Z')||c=='_'||c=='.'||c=='$'){
35519571Smckusick 				ctokn = cnamp;
35619571Smckusick 				while(	(c>='a'&&c<='z') ||
35719571Smckusick 					(c>='A'&&c<='Z') ||
35819571Smckusick 					(c>='0'&&c<='9') ||
35919571Smckusick 					c=='_' || c=='.' || c=='$' ) {
36019571Smckusick 					chstash( c );
36119571Smckusick 					if( peekc>=0 ) { c = peekc; peekc = -1; }
36219571Smckusick 					else c = fgetc( cin);
36319571Smckusick 					}
36419571Smckusick 				}
36519571Smckusick 			else return(c);
36619571Smckusick 
36719571Smckusick 			peekc=c;
36819571Smckusick 			}
36919571Smckusick 	chstash( '\0' );
37019571Smckusick 
37119571Smckusick 	if( reserve ){ /* find a reserved word */
37219571Smckusick 		if( compare("term")) return( TERM );
37319571Smckusick 		if( compare("TERM")) return( TERM );
37419571Smckusick 		if( compare("token")) return( TERM );
37519571Smckusick 		if( compare("TOKEN")) return( TERM );
37619571Smckusick 		if( compare("left")) return( LEFT );
37719571Smckusick 		if( compare("LEFT")) return( LEFT );
37819571Smckusick 		if( compare("nonassoc")) return( BINARY );
37919571Smckusick 		if( compare("NONASSOC")) return( BINARY );
38019571Smckusick 		if( compare("binary")) return( BINARY );
38119571Smckusick 		if( compare("BINARY")) return( BINARY );
38219571Smckusick 		if( compare("right")) return( RIGHT );
38319571Smckusick 		if( compare("RIGHT")) return( RIGHT );
38419571Smckusick 		if( compare("prec")) return( PREC );
38519571Smckusick 		if( compare("PREC")) return( PREC );
38619571Smckusick 		error("invalid escape, or illegal reserved word: %s", ctokn );
38719571Smckusick 		}
38819571Smckusick 
38919571Smckusick 	/* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
39019571Smckusick 
39119571Smckusick   look:
39219571Smckusick 	while( peekc==' ' || peekc=='\t' || peekc == '\n' || peekc == '\014' )
39319571Smckusick 	{
39419571Smckusick 		if( peekc == '\n' ) ++peekline;
39519571Smckusick 		peekc = fgetc( cin);
39619571Smckusick 	}
39719571Smckusick 
39819571Smckusick 	if( peekc != ':' ) return( IDENTIFIER );
39919571Smckusick 	peekc = -1;
40019571Smckusick 	lineno += peekline;
40119571Smckusick 	peekline = 0;
40219571Smckusick 	return( C_IDENTIFIER );
40319571Smckusick }
chfind(t)40419571Smckusick chfind(t)
40519571Smckusick 
40619571Smckusick {	int i,j;
40719571Smckusick 
40819571Smckusick 	if (ctokn[0]==' ')t=0;
40919571Smckusick 	for(i=1;i<=nterms;i++)
41019571Smckusick 		if(compare(trmset[i].name)){
41119571Smckusick 			cnamp = ctokn;
41219571Smckusick 			return( i );
41319571Smckusick 			}
41419571Smckusick 	for(i=1;i<=nnonter;i++)
41519571Smckusick 		if(compare(nontrst[i].name)) {
41619571Smckusick 			cnamp = ctokn;
41719571Smckusick 			return( i+NTBASE );
41819571Smckusick 			}
41919571Smckusick 	/* cannot find name */
42019571Smckusick 	if( t>1 && ctokn[0] != ' ' )
42119571Smckusick 		error( "%s should have been defined earlier", ctokn );
42219571Smckusick 	return( defin( t ) );
42319571Smckusick 	}
42419571Smckusick 
cpycode()42519571Smckusick cpycode(){ /* copies code between \{ and \} */
42619571Smckusick 
42719571Smckusick 	int c;
42819571Smckusick 	c = fgetc( cin);
42919571Smckusick 	if( c == '\n' ) {
43019571Smckusick 		c = fgetc( cin);
43119571Smckusick 		lineno++;
43219571Smckusick 		}
43319571Smckusick 	while( c != EOF ){
43419571Smckusick 		if( c=='\\' )
43519571Smckusick 			if( (c=fgetc( cin)) == '}' ) return;
43619571Smckusick 			else fputc('\\',cout);
43719571Smckusick 		if( c=='%' )
43819571Smckusick 			if( (c=fgetc( cin)) == '}' ) return;
43919571Smckusick 			else fputc('%',cout);
44019571Smckusick 		fputc( c, cout );
44119571Smckusick 		if( c == '\n' ) ++lineno;
44219571Smckusick 		c = fgetc( cin);
44319571Smckusick 		}
44419571Smckusick 	error("eof before %%}");
44519571Smckusick 	}
44619571Smckusick 
cpyact()44719571Smckusick cpyact(){ /* copy C action to the next ; or closing } */
44819571Smckusick 	int brac, c, match, *i, j, s;
44919571Smckusick 
45019571Smckusick 	brac = 0;
45119571Smckusick 
45219571Smckusick loop:
45319571Smckusick 	c = fgetc( cin);
45419571Smckusick swt:
45519571Smckusick 	switch( c ){
45619571Smckusick 
45719571Smckusick case ';':
45819571Smckusick 		if( brac == 0 ){
45919571Smckusick 			fputc( c, cout );
46019571Smckusick 			return;
46119571Smckusick 			}
46219571Smckusick 		goto lcopy;
46319571Smckusick 
46419571Smckusick case '{':
46519571Smckusick 		brac++;
46619571Smckusick 		goto lcopy;
46719571Smckusick 
46819571Smckusick case '$':
46919571Smckusick 		s = 1;
47019571Smckusick 		c = fgetc( cin);
47119571Smckusick 		if( c == '$' ){
47219571Smckusick 			fprintf( cout , "yyval");
47319571Smckusick 			goto loop;
47419571Smckusick 			}
47519571Smckusick 		if( c == '-' ){
47619571Smckusick 			s = -s;
47719571Smckusick 			c = fgetc( cin);
47819571Smckusick 			}
47919571Smckusick 		if( c>='0' && c <= '9' ){
48019571Smckusick 			j=0;
48119571Smckusick 			while( c>='0' && c<= '9' ){
48219571Smckusick 				j= j*10+c-'0';
48319571Smckusick 				c = fgetc( cin);
48419571Smckusick 				}
48519571Smckusick 			if( rflag ) fprintf( cout ,  "yyvalv(yypv%c%d)", s==1?'+':'-', j );
48619571Smckusick 			else fprintf( cout , "yypv[%d]", s*j );
48719571Smckusick 			goto swt;
48819571Smckusick 			}
48919571Smckusick 		fputc( '$' , cout);
49019571Smckusick 		if( s<0 ) fputc('-', cout);
49119571Smckusick 		goto swt;
49219571Smckusick 
49319571Smckusick case '}':
49419571Smckusick 		brac--;
49519571Smckusick 		if( brac == 0 ){
49619571Smckusick 			fputc( c , cout);
49719571Smckusick 			return;
49819571Smckusick 			}
49919571Smckusick 		goto lcopy;
50019571Smckusick 
50119571Smckusick case '/':	/* look for comments */
50219571Smckusick 		fputc( c ,cout);
50319571Smckusick 		c = fgetc( cin);
50419571Smckusick 		if( c != '*' ) goto swt;
50519571Smckusick 
50619571Smckusick 		/* it really is a comment */
50719571Smckusick 
50819571Smckusick 		fputc( c , cout);
50919571Smckusick 		while( (c=fgetc( cin)) != EOF ){
51019571Smckusick 			if( c=='*' ){
51119571Smckusick 				fputc( c , cout);
51219571Smckusick 				if( (c=fgetc( cin)) == '/' ) goto lcopy;
51319571Smckusick 				}
51419571Smckusick 			fputc( c , cout);
51519571Smckusick 			}
51619571Smckusick 		error( "EOF inside comment" );
51719571Smckusick 
51819571Smckusick case '\'':	/* character constant */
51919571Smckusick 		match = '\'';
52019571Smckusick 		goto string;
52119571Smckusick 
52219571Smckusick case '"':	/* character string */
52319571Smckusick 		match = '"';
52419571Smckusick 
52519571Smckusick 	string:
52619571Smckusick 
52719571Smckusick 		fputc( c , cout);
52819571Smckusick 		while( (c=fgetc( cin)) != EOF ){
52919571Smckusick 
53019571Smckusick 			if( c=='\\' ){
53119571Smckusick 				fputc( c , cout);
53219571Smckusick 				c=fgetc( cin);
53319571Smckusick 				}
53419571Smckusick 			else if( c==match ) goto lcopy;
53519571Smckusick 			fputc( c , cout);
53619571Smckusick 			}
53719571Smckusick 		error( "EOF in string or character constant" );
53819571Smckusick 
53919571Smckusick case '\0':
54019571Smckusick 		error("action does not terminate");
54119571Smckusick case '\n':	++lineno;
54219571Smckusick 		goto lcopy;
54319571Smckusick 
54419571Smckusick 		}
54519571Smckusick 
54619571Smckusick lcopy:
54719571Smckusick 	fputc( c , cout);
54819571Smckusick 	goto loop;
54919571Smckusick 	}
550