xref: /csrg-svn/usr.bin/f77/pass1.tahoe/lex.c (revision 37426)
1*37426Sbostic /*
2*37426Sbostic  * Copyright (c) 1980 Regents of the University of California.
3*37426Sbostic  * All rights reserved.  The Berkeley software License Agreement
4*37426Sbostic  * specifies the terms and conditions for redistribution.
5*37426Sbostic  */
6*37426Sbostic 
7*37426Sbostic #ifndef lint
8*37426Sbostic static char sccsid[] = "@(#)lex.c	5.1 (Berkeley) 6/7/85";
9*37426Sbostic #endif not lint
10*37426Sbostic 
11*37426Sbostic /*
12*37426Sbostic  * lex.c
13*37426Sbostic  *
14*37426Sbostic  * Lexical scanner routines for the f77 compiler, pass 1, 4.2 BSD.
15*37426Sbostic  *
16*37426Sbostic  * University of Utah CS Dept modification history:
17*37426Sbostic  *
18*37426Sbostic  * $Log:	lex.c,v $
19*37426Sbostic  * Revision 1.2  84/10/27  02:20:09  donn
20*37426Sbostic  * Fixed bug where the input file and the name field of the include file
21*37426Sbostic  * structure shared -- when the input file name was freed, the include file
22*37426Sbostic  * name got stomped on, leading to peculiar error messages.
23*37426Sbostic  *
24*37426Sbostic  */
25*37426Sbostic 
26*37426Sbostic #include "defs.h"
27*37426Sbostic #include "tokdefs.h"
28*37426Sbostic 
29*37426Sbostic # define BLANK	' '
30*37426Sbostic # define MYQUOTE (2)
31*37426Sbostic # define SEOF 0
32*37426Sbostic 
33*37426Sbostic /* card types */
34*37426Sbostic 
35*37426Sbostic # define STEOF 1
36*37426Sbostic # define STINITIAL 2
37*37426Sbostic # define STCONTINUE 3
38*37426Sbostic 
39*37426Sbostic /* lex states */
40*37426Sbostic 
41*37426Sbostic #define NEWSTMT	1
42*37426Sbostic #define FIRSTTOKEN	2
43*37426Sbostic #define OTHERTOKEN	3
44*37426Sbostic #define RETEOS	4
45*37426Sbostic 
46*37426Sbostic 
47*37426Sbostic LOCAL int stkey;
48*37426Sbostic LOCAL int lastend = 1;
49*37426Sbostic ftnint yystno;
50*37426Sbostic flag intonly;
51*37426Sbostic LOCAL long int stno;
52*37426Sbostic LOCAL long int nxtstno;
53*37426Sbostic LOCAL int parlev;
54*37426Sbostic LOCAL int expcom;
55*37426Sbostic LOCAL int expeql;
56*37426Sbostic LOCAL char *nextch;
57*37426Sbostic LOCAL char *lastch;
58*37426Sbostic LOCAL char *nextcd 	= NULL;
59*37426Sbostic LOCAL char *endcd;
60*37426Sbostic LOCAL int prevlin;
61*37426Sbostic LOCAL int thislin;
62*37426Sbostic LOCAL int code;
63*37426Sbostic LOCAL int lexstate	= NEWSTMT;
64*37426Sbostic LOCAL char s[1390];
65*37426Sbostic LOCAL char *send	= s+20*66;
66*37426Sbostic LOCAL int nincl	= 0;
67*37426Sbostic LOCAL char *newname = NULL;
68*37426Sbostic 
69*37426Sbostic struct Inclfile
70*37426Sbostic 	{
71*37426Sbostic 	struct Inclfile *inclnext;
72*37426Sbostic 	FILEP inclfp;
73*37426Sbostic 	char *inclname;
74*37426Sbostic 	int incllno;
75*37426Sbostic 	char *incllinp;
76*37426Sbostic 	int incllen;
77*37426Sbostic 	int inclcode;
78*37426Sbostic 	ftnint inclstno;
79*37426Sbostic 	} ;
80*37426Sbostic 
81*37426Sbostic LOCAL struct Inclfile *inclp	=  NULL;
82*37426Sbostic LOCAL struct Keylist { char *keyname; int keyval; char notinf66; } ;
83*37426Sbostic LOCAL struct Punctlist { char punchar; int punval; };
84*37426Sbostic LOCAL struct Fmtlist { char fmtchar; int fmtval; };
85*37426Sbostic LOCAL struct Dotlist { char *dotname; int dotval; };
86*37426Sbostic LOCAL struct Keylist *keystart[26], *keyend[26];
87*37426Sbostic 
88*37426Sbostic 
89*37426Sbostic 
90*37426Sbostic 
91*37426Sbostic inilex(name)
92*37426Sbostic char *name;
93*37426Sbostic {
94*37426Sbostic nincl = 0;
95*37426Sbostic inclp = NULL;
96*37426Sbostic doinclude(name);
97*37426Sbostic lexstate = NEWSTMT;
98*37426Sbostic return(NO);
99*37426Sbostic }
100*37426Sbostic 
101*37426Sbostic 
102*37426Sbostic 
103*37426Sbostic /* throw away the rest of the current line */
104*37426Sbostic flline()
105*37426Sbostic {
106*37426Sbostic lexstate = RETEOS;
107*37426Sbostic }
108*37426Sbostic 
109*37426Sbostic 
110*37426Sbostic 
111*37426Sbostic char *lexline(n)
112*37426Sbostic int *n;
113*37426Sbostic {
114*37426Sbostic *n = (lastch - nextch) + 1;
115*37426Sbostic return(nextch);
116*37426Sbostic }
117*37426Sbostic 
118*37426Sbostic 
119*37426Sbostic 
120*37426Sbostic 
121*37426Sbostic 
122*37426Sbostic doinclude(name)
123*37426Sbostic char *name;
124*37426Sbostic {
125*37426Sbostic FILEP fp;
126*37426Sbostic struct Inclfile *t;
127*37426Sbostic char temp[100];
128*37426Sbostic register char *lastslash, *s;
129*37426Sbostic 
130*37426Sbostic if(inclp)
131*37426Sbostic 	{
132*37426Sbostic 	inclp->incllno = thislin;
133*37426Sbostic 	inclp->inclcode = code;
134*37426Sbostic 	inclp->inclstno = nxtstno;
135*37426Sbostic 	if(nextcd)
136*37426Sbostic 		inclp->incllinp = copyn(inclp->incllen = endcd-nextcd , nextcd);
137*37426Sbostic 	else
138*37426Sbostic 		inclp->incllinp = 0;
139*37426Sbostic 	}
140*37426Sbostic nextcd = NULL;
141*37426Sbostic 
142*37426Sbostic if(++nincl >= MAXINCLUDES)
143*37426Sbostic 	fatal("includes nested too deep");
144*37426Sbostic if(name[0] == '\0')
145*37426Sbostic 	fp = stdin;
146*37426Sbostic else if(name[0]=='/' || inclp==NULL)
147*37426Sbostic 	fp = fopen(name, "r");
148*37426Sbostic else	{
149*37426Sbostic 	lastslash = NULL;
150*37426Sbostic 	for(s = inclp->inclname ; *s ; ++s)
151*37426Sbostic 		if(*s == '/')
152*37426Sbostic 			lastslash = s;
153*37426Sbostic 	if(lastslash)
154*37426Sbostic 		{
155*37426Sbostic 		*lastslash = '\0';
156*37426Sbostic 		sprintf(temp, "%s/%s", inclp->inclname, name);
157*37426Sbostic 		*lastslash = '/';
158*37426Sbostic 		}
159*37426Sbostic 	else
160*37426Sbostic 		strcpy(temp, name);
161*37426Sbostic 
162*37426Sbostic 	if( (fp = fopen(temp, "r")) == NULL )
163*37426Sbostic 		{
164*37426Sbostic 		sprintf(temp, "/usr/include/%s", name);
165*37426Sbostic 		fp = fopen(temp, "r");
166*37426Sbostic 		}
167*37426Sbostic 	if(fp)
168*37426Sbostic 		name = copys(temp);
169*37426Sbostic 	}
170*37426Sbostic 
171*37426Sbostic if( fp )
172*37426Sbostic 	{
173*37426Sbostic 	t = inclp;
174*37426Sbostic 	inclp = ALLOC(Inclfile);
175*37426Sbostic 	inclp->inclnext = t;
176*37426Sbostic 	prevlin = thislin = 0;
177*37426Sbostic 	inclp->inclname = name;
178*37426Sbostic 	infname = copys(name);
179*37426Sbostic 	infile = inclp->inclfp = fp;
180*37426Sbostic 	}
181*37426Sbostic else
182*37426Sbostic 	{
183*37426Sbostic 	fprintf(diagfile, "Cannot open file %s", name);
184*37426Sbostic 	done(1);
185*37426Sbostic 	}
186*37426Sbostic }
187*37426Sbostic 
188*37426Sbostic 
189*37426Sbostic 
190*37426Sbostic 
191*37426Sbostic LOCAL popinclude()
192*37426Sbostic {
193*37426Sbostic struct Inclfile *t;
194*37426Sbostic register char *p;
195*37426Sbostic register int k;
196*37426Sbostic 
197*37426Sbostic if(infile != stdin)
198*37426Sbostic 	clf(&infile);
199*37426Sbostic free(infname);
200*37426Sbostic 
201*37426Sbostic --nincl;
202*37426Sbostic t = inclp->inclnext;
203*37426Sbostic free(inclp->inclname);
204*37426Sbostic free( (charptr) inclp);
205*37426Sbostic inclp = t;
206*37426Sbostic if(inclp == NULL)
207*37426Sbostic 	return(NO);
208*37426Sbostic 
209*37426Sbostic infile = inclp->inclfp;
210*37426Sbostic infname = copys(inclp->inclname);
211*37426Sbostic prevlin = thislin = inclp->incllno;
212*37426Sbostic code = inclp->inclcode;
213*37426Sbostic stno = nxtstno = inclp->inclstno;
214*37426Sbostic if(inclp->incllinp)
215*37426Sbostic 	{
216*37426Sbostic 	endcd = nextcd = s;
217*37426Sbostic 	k = inclp->incllen;
218*37426Sbostic 	p = inclp->incllinp;
219*37426Sbostic 	while(--k >= 0)
220*37426Sbostic 		*endcd++ = *p++;
221*37426Sbostic 	free( (charptr) (inclp->incllinp) );
222*37426Sbostic 	}
223*37426Sbostic else
224*37426Sbostic 	nextcd = NULL;
225*37426Sbostic return(YES);
226*37426Sbostic }
227*37426Sbostic 
228*37426Sbostic 
229*37426Sbostic 
230*37426Sbostic 
231*37426Sbostic yylex()
232*37426Sbostic {
233*37426Sbostic static int  tokno;
234*37426Sbostic 
235*37426Sbostic 	switch(lexstate)
236*37426Sbostic 	{
237*37426Sbostic case NEWSTMT :	/* need a new statement */
238*37426Sbostic 	if(getcds() == STEOF)
239*37426Sbostic 		return(SEOF);
240*37426Sbostic 	lastend =  stkey == SEND;
241*37426Sbostic 	crunch();
242*37426Sbostic 	tokno = 0;
243*37426Sbostic 	lexstate = FIRSTTOKEN;
244*37426Sbostic 	yystno = stno;
245*37426Sbostic 	stno = nxtstno;
246*37426Sbostic 	toklen = 0;
247*37426Sbostic 	return(SLABEL);
248*37426Sbostic 
249*37426Sbostic first:
250*37426Sbostic case FIRSTTOKEN :	/* first step on a statement */
251*37426Sbostic 	analyz();
252*37426Sbostic 	lexstate = OTHERTOKEN;
253*37426Sbostic 	tokno = 1;
254*37426Sbostic 	return(stkey);
255*37426Sbostic 
256*37426Sbostic case OTHERTOKEN :	/* return next token */
257*37426Sbostic 	if(nextch > lastch)
258*37426Sbostic 		goto reteos;
259*37426Sbostic 	++tokno;
260*37426Sbostic 	if( (stkey==SLOGIF || stkey==SELSEIF) && parlev==0 && tokno>3)
261*37426Sbostic 		goto first;
262*37426Sbostic 
263*37426Sbostic 	if(stkey==SASSIGN && tokno==3 && nextch<lastch &&
264*37426Sbostic 		nextch[0]=='t' && nextch[1]=='o')
265*37426Sbostic 			{
266*37426Sbostic 			nextch+=2;
267*37426Sbostic 			return(STO);
268*37426Sbostic 			}
269*37426Sbostic 	return(gettok());
270*37426Sbostic 
271*37426Sbostic reteos:
272*37426Sbostic case RETEOS:
273*37426Sbostic 	lexstate = NEWSTMT;
274*37426Sbostic 	return(SEOS);
275*37426Sbostic 	}
276*37426Sbostic fatali("impossible lexstate %d", lexstate);
277*37426Sbostic /* NOTREACHED */
278*37426Sbostic }
279*37426Sbostic 
280*37426Sbostic LOCAL getcds()
281*37426Sbostic {
282*37426Sbostic register char *p, *q;
283*37426Sbostic 
284*37426Sbostic 	if (newname)
285*37426Sbostic 		{
286*37426Sbostic 		free(infname);
287*37426Sbostic 		infname = newname;
288*37426Sbostic 		newname = NULL;
289*37426Sbostic 		}
290*37426Sbostic 
291*37426Sbostic top:
292*37426Sbostic 	if(nextcd == NULL)
293*37426Sbostic 		{
294*37426Sbostic 		code = getcd( nextcd = s );
295*37426Sbostic 		stno = nxtstno;
296*37426Sbostic 		if (newname)
297*37426Sbostic 			{
298*37426Sbostic 			free(infname);
299*37426Sbostic 			infname = newname;
300*37426Sbostic 			newname = NULL;
301*37426Sbostic 			}
302*37426Sbostic 		prevlin = thislin;
303*37426Sbostic 		}
304*37426Sbostic 	if(code == STEOF)
305*37426Sbostic 		if( popinclude() )
306*37426Sbostic 			goto top;
307*37426Sbostic 		else
308*37426Sbostic 			return(STEOF);
309*37426Sbostic 
310*37426Sbostic 	if(code == STCONTINUE)
311*37426Sbostic 		{
312*37426Sbostic 		if (newname)
313*37426Sbostic 			{
314*37426Sbostic 			free(infname);
315*37426Sbostic 			infname = newname;
316*37426Sbostic 			newname = NULL;
317*37426Sbostic 			}
318*37426Sbostic 		lineno = thislin;
319*37426Sbostic 		err("illegal continuation card ignored");
320*37426Sbostic 		nextcd = NULL;
321*37426Sbostic 		goto top;
322*37426Sbostic 		}
323*37426Sbostic 
324*37426Sbostic 	if(nextcd > s)
325*37426Sbostic 		{
326*37426Sbostic 		q = nextcd;
327*37426Sbostic 		p = s;
328*37426Sbostic 		while(q < endcd)
329*37426Sbostic 			*p++ = *q++;
330*37426Sbostic 		endcd = p;
331*37426Sbostic 		}
332*37426Sbostic 	for(nextcd = endcd ;
333*37426Sbostic 		nextcd+66<=send && (code = getcd(nextcd))==STCONTINUE ;
334*37426Sbostic 		nextcd = endcd )
335*37426Sbostic 			;
336*37426Sbostic 	nextch = s;
337*37426Sbostic 	lastch = nextcd - 1;
338*37426Sbostic 	if(nextcd >= send)
339*37426Sbostic 		nextcd = NULL;
340*37426Sbostic 	lineno = prevlin;
341*37426Sbostic 	prevlin = thislin;
342*37426Sbostic 	return(STINITIAL);
343*37426Sbostic }
344*37426Sbostic 
345*37426Sbostic LOCAL getcd(b)
346*37426Sbostic register char *b;
347*37426Sbostic {
348*37426Sbostic register int c;
349*37426Sbostic register char *p, *bend;
350*37426Sbostic int speclin;
351*37426Sbostic static char a[6];
352*37426Sbostic static char *aend	= a+6;
353*37426Sbostic int num;
354*37426Sbostic 
355*37426Sbostic top:
356*37426Sbostic 	endcd = b;
357*37426Sbostic 	bend = b+66;
358*37426Sbostic 	speclin = NO;
359*37426Sbostic 
360*37426Sbostic 	if( (c = getc(infile)) == '&')
361*37426Sbostic 		{
362*37426Sbostic 		a[0] = BLANK;
363*37426Sbostic 		a[5] = 'x';
364*37426Sbostic 		speclin = YES;
365*37426Sbostic 		bend = send;
366*37426Sbostic 		}
367*37426Sbostic 	else if(c=='c' || c=='C' || c=='*')
368*37426Sbostic 		{
369*37426Sbostic 		while( (c = getc(infile)) != '\n')
370*37426Sbostic 			if(c == EOF)
371*37426Sbostic 				return(STEOF);
372*37426Sbostic 		++thislin;
373*37426Sbostic 		goto top;
374*37426Sbostic 		}
375*37426Sbostic 	else if(c == '#')
376*37426Sbostic 		{
377*37426Sbostic 		c = getc(infile);
378*37426Sbostic 		while (c == BLANK || c == '\t')
379*37426Sbostic 			c = getc(infile);
380*37426Sbostic 
381*37426Sbostic 		num = 0;
382*37426Sbostic 		while (isdigit(c))
383*37426Sbostic 			{
384*37426Sbostic 			num = 10*num + c - '0';
385*37426Sbostic 			c = getc(infile);
386*37426Sbostic 			}
387*37426Sbostic 		thislin = num - 1;
388*37426Sbostic 
389*37426Sbostic 		while (c == BLANK || c == '\t')
390*37426Sbostic 			c = getc(infile);
391*37426Sbostic 
392*37426Sbostic 		if (c == '"')
393*37426Sbostic 			{
394*37426Sbostic 			char fname[1024];
395*37426Sbostic 			int len = 0;
396*37426Sbostic 
397*37426Sbostic 			c = getc(infile);
398*37426Sbostic 			while (c != '"' && c != '\n')
399*37426Sbostic 				{
400*37426Sbostic 				fname[len++] = c;
401*37426Sbostic 				c = getc(infile);
402*37426Sbostic 				}
403*37426Sbostic 			fname[len++] = '\0';
404*37426Sbostic 
405*37426Sbostic 			if (newname)
406*37426Sbostic 				free(newname);
407*37426Sbostic 			newname = (char *) ckalloc(len);
408*37426Sbostic 			strcpy(newname, fname);
409*37426Sbostic 			}
410*37426Sbostic 
411*37426Sbostic 		while (c != '\n')
412*37426Sbostic 			if (c == EOF)
413*37426Sbostic 				return (STEOF);
414*37426Sbostic 			else
415*37426Sbostic 				c = getc(infile);
416*37426Sbostic 		goto top;
417*37426Sbostic 		}
418*37426Sbostic 
419*37426Sbostic 	else if(c != EOF)
420*37426Sbostic 		{
421*37426Sbostic 		/* a tab in columns 1-6 skips to column 7 */
422*37426Sbostic 		ungetc(c, infile);
423*37426Sbostic 		for(p=a; p<aend && (c=getc(infile)) != '\n' && c!=EOF; )
424*37426Sbostic 			if(c == '\t')
425*37426Sbostic 				{
426*37426Sbostic 				while(p < aend)
427*37426Sbostic 					*p++ = BLANK;
428*37426Sbostic 				speclin = YES;
429*37426Sbostic 				bend = send;
430*37426Sbostic 				}
431*37426Sbostic 			else
432*37426Sbostic 				*p++ = c;
433*37426Sbostic 		}
434*37426Sbostic 	if(c == EOF)
435*37426Sbostic 		return(STEOF);
436*37426Sbostic 	if(c == '\n')
437*37426Sbostic 		{
438*37426Sbostic 		while(p < aend)
439*37426Sbostic 			*p++ = BLANK;
440*37426Sbostic 		if( ! speclin )
441*37426Sbostic 			while(endcd < bend)
442*37426Sbostic 				*endcd++ = BLANK;
443*37426Sbostic 		}
444*37426Sbostic 	else	{	/* read body of line */
445*37426Sbostic 		while( endcd<bend && (c=getc(infile)) != '\n' && c!=EOF )
446*37426Sbostic 			*endcd++ = c;
447*37426Sbostic 		if(c == EOF)
448*37426Sbostic 			return(STEOF);
449*37426Sbostic 		if(c != '\n')
450*37426Sbostic 			{
451*37426Sbostic 			while( (c=getc(infile)) != '\n')
452*37426Sbostic 				if(c == EOF)
453*37426Sbostic 					return(STEOF);
454*37426Sbostic 			}
455*37426Sbostic 
456*37426Sbostic 		if( ! speclin )
457*37426Sbostic 			while(endcd < bend)
458*37426Sbostic 				*endcd++ = BLANK;
459*37426Sbostic 		}
460*37426Sbostic 	++thislin;
461*37426Sbostic 	if( !isspace(a[5]) && a[5]!='0')
462*37426Sbostic 		return(STCONTINUE);
463*37426Sbostic 	for(p=a; p<aend; ++p)
464*37426Sbostic 		if( !isspace(*p) ) goto initline;
465*37426Sbostic 	for(p = b ; p<endcd ; ++p)
466*37426Sbostic 		if( !isspace(*p) ) goto initline;
467*37426Sbostic 	goto top;
468*37426Sbostic 
469*37426Sbostic initline:
470*37426Sbostic 	nxtstno = 0;
471*37426Sbostic 	for(p = a ; p<a+5 ; ++p)
472*37426Sbostic 		if( !isspace(*p) )
473*37426Sbostic 			if(isdigit(*p))
474*37426Sbostic 				nxtstno = 10*nxtstno + (*p - '0');
475*37426Sbostic 			else	{
476*37426Sbostic 				if (newname)
477*37426Sbostic 					{
478*37426Sbostic 					free(infname);
479*37426Sbostic 					infname = newname;
480*37426Sbostic 					newname = NULL;
481*37426Sbostic 					}
482*37426Sbostic 				lineno = thislin;
483*37426Sbostic 				err("nondigit in statement number field");
484*37426Sbostic 				nxtstno = 0;
485*37426Sbostic 				break;
486*37426Sbostic 				}
487*37426Sbostic 	return(STINITIAL);
488*37426Sbostic }
489*37426Sbostic 
490*37426Sbostic LOCAL crunch()
491*37426Sbostic {
492*37426Sbostic register char *i, *j, *j0, *j1, *prvstr;
493*37426Sbostic int ten, nh, quote;
494*37426Sbostic 
495*37426Sbostic /* i is the next input character to be looked at
496*37426Sbostic j is the next output character */
497*37426Sbostic parlev = 0;
498*37426Sbostic expcom = 0;	/* exposed ','s */
499*37426Sbostic expeql = 0;	/* exposed equal signs */
500*37426Sbostic j = s;
501*37426Sbostic prvstr = s;
502*37426Sbostic for(i=s ; i<=lastch ; ++i)
503*37426Sbostic 	{
504*37426Sbostic 	if(isspace(*i) )
505*37426Sbostic 		continue;
506*37426Sbostic 	if(*i=='\'' ||  *i=='"')
507*37426Sbostic 		{
508*37426Sbostic 		quote = *i;
509*37426Sbostic 		*j = MYQUOTE; /* special marker */
510*37426Sbostic 		for(;;)
511*37426Sbostic 			{
512*37426Sbostic 			if(++i > lastch)
513*37426Sbostic 				{
514*37426Sbostic 				err("unbalanced quotes; closing quote supplied");
515*37426Sbostic 				break;
516*37426Sbostic 				}
517*37426Sbostic 			if(*i == quote)
518*37426Sbostic 				if(i<lastch && i[1]==quote) ++i;
519*37426Sbostic 				else break;
520*37426Sbostic 			else if(*i=='\\' && i<lastch)
521*37426Sbostic 				switch(*++i)
522*37426Sbostic 					{
523*37426Sbostic 					case 't':
524*37426Sbostic 						*i = '\t'; break;
525*37426Sbostic 					case 'b':
526*37426Sbostic 						*i = '\b'; break;
527*37426Sbostic 					case 'n':
528*37426Sbostic 						*i = '\n'; break;
529*37426Sbostic 					case 'f':
530*37426Sbostic 						*i = '\f'; break;
531*37426Sbostic 					case 'v':
532*37426Sbostic 						*i = '\v'; break;
533*37426Sbostic 					case '0':
534*37426Sbostic 						*i = '\0'; break;
535*37426Sbostic 					default:
536*37426Sbostic 						break;
537*37426Sbostic 					}
538*37426Sbostic 			*++j = *i;
539*37426Sbostic 			}
540*37426Sbostic 		j[1] = MYQUOTE;
541*37426Sbostic 		j += 2;
542*37426Sbostic 		prvstr = j;
543*37426Sbostic 		}
544*37426Sbostic 	else if( (*i=='h' || *i=='H')  && j>prvstr)	/* test for Hollerith strings */
545*37426Sbostic 		{
546*37426Sbostic 		if( ! isdigit(j[-1])) goto copychar;
547*37426Sbostic 		nh = j[-1] - '0';
548*37426Sbostic 		ten = 10;
549*37426Sbostic 		j1 = prvstr - 1;
550*37426Sbostic 		if (j1<j-5) j1=j-5;
551*37426Sbostic 		for(j0=j-2 ; j0>j1; -- j0)
552*37426Sbostic 			{
553*37426Sbostic 			if( ! isdigit(*j0 ) ) break;
554*37426Sbostic 			nh += ten * (*j0-'0');
555*37426Sbostic 			ten*=10;
556*37426Sbostic 			}
557*37426Sbostic 		if(j0 <= j1) goto copychar;
558*37426Sbostic /* a hollerith must be preceded by a punctuation mark.
559*37426Sbostic    '*' is possible only as repetition factor in a data statement
560*37426Sbostic    not, in particular, in character*2h
561*37426Sbostic */
562*37426Sbostic 
563*37426Sbostic 		if( !(*j0=='*'&&s[0]=='d') && *j0!='/' && *j0!='(' &&
564*37426Sbostic 			*j0!=',' && *j0!='=' && *j0!='.')
565*37426Sbostic 				goto copychar;
566*37426Sbostic 		if(i+nh > lastch)
567*37426Sbostic 			{
568*37426Sbostic 			erri("%dH too big", nh);
569*37426Sbostic 			nh = lastch - i;
570*37426Sbostic 			}
571*37426Sbostic 		j0[1] = MYQUOTE; /* special marker */
572*37426Sbostic 		j = j0 + 1;
573*37426Sbostic 		while(nh-- > 0)
574*37426Sbostic 			{
575*37426Sbostic 			if(*++i == '\\')
576*37426Sbostic 				switch(*++i)
577*37426Sbostic 					{
578*37426Sbostic 					case 't':
579*37426Sbostic 						*i = '\t'; break;
580*37426Sbostic 					case 'b':
581*37426Sbostic 						*i = '\b'; break;
582*37426Sbostic 					case 'n':
583*37426Sbostic 						*i = '\n'; break;
584*37426Sbostic 					case 'f':
585*37426Sbostic 						*i = '\f'; break;
586*37426Sbostic 					case '0':
587*37426Sbostic 						*i = '\0'; break;
588*37426Sbostic 					default:
589*37426Sbostic 						break;
590*37426Sbostic 					}
591*37426Sbostic 			*++j = *i;
592*37426Sbostic 			}
593*37426Sbostic 		j[1] = MYQUOTE;
594*37426Sbostic 		j+=2;
595*37426Sbostic 		prvstr = j;
596*37426Sbostic 		}
597*37426Sbostic 	else	{
598*37426Sbostic 		if(*i == '(') ++parlev;
599*37426Sbostic 		else if(*i == ')') --parlev;
600*37426Sbostic 		else if(parlev == 0)
601*37426Sbostic 			if(*i == '=') expeql = 1;
602*37426Sbostic 			else if(*i == ',') expcom = 1;
603*37426Sbostic copychar:		/*not a string or space -- copy, shifting case if necessary */
604*37426Sbostic 		if(shiftcase && isupper(*i))
605*37426Sbostic 			*j++ = tolower(*i);
606*37426Sbostic 		else	*j++ = *i;
607*37426Sbostic 		}
608*37426Sbostic 	}
609*37426Sbostic lastch = j - 1;
610*37426Sbostic nextch = s;
611*37426Sbostic }
612*37426Sbostic 
613*37426Sbostic LOCAL analyz()
614*37426Sbostic {
615*37426Sbostic register char *i;
616*37426Sbostic 
617*37426Sbostic 	if(parlev != 0)
618*37426Sbostic 		{
619*37426Sbostic 		err("unbalanced parentheses, statement skipped");
620*37426Sbostic 		stkey = SUNKNOWN;
621*37426Sbostic 		return;
622*37426Sbostic 		}
623*37426Sbostic 	if(nextch+2<=lastch && nextch[0]=='i' && nextch[1]=='f' && nextch[2]=='(')
624*37426Sbostic 		{
625*37426Sbostic /* assignment or if statement -- look at character after balancing paren */
626*37426Sbostic 		parlev = 1;
627*37426Sbostic 		for(i=nextch+3 ; i<=lastch; ++i)
628*37426Sbostic 			if(*i == (MYQUOTE))
629*37426Sbostic 				{
630*37426Sbostic 				while(*++i != MYQUOTE)
631*37426Sbostic 					;
632*37426Sbostic 				}
633*37426Sbostic 			else if(*i == '(')
634*37426Sbostic 				++parlev;
635*37426Sbostic 			else if(*i == ')')
636*37426Sbostic 				{
637*37426Sbostic 				if(--parlev == 0)
638*37426Sbostic 					break;
639*37426Sbostic 				}
640*37426Sbostic 		if(i >= lastch)
641*37426Sbostic 			stkey = SLOGIF;
642*37426Sbostic 		else if(i[1] == '=')
643*37426Sbostic 			stkey = SLET;
644*37426Sbostic 		else if( isdigit(i[1]) )
645*37426Sbostic 			stkey = SARITHIF;
646*37426Sbostic 		else	stkey = SLOGIF;
647*37426Sbostic 		if(stkey != SLET)
648*37426Sbostic 			nextch += 2;
649*37426Sbostic 		}
650*37426Sbostic 	else if(expeql) /* may be an assignment */
651*37426Sbostic 		{
652*37426Sbostic 		if(expcom && nextch<lastch &&
653*37426Sbostic 			nextch[0]=='d' && nextch[1]=='o')
654*37426Sbostic 				{
655*37426Sbostic 				stkey = SDO;
656*37426Sbostic 				nextch += 2;
657*37426Sbostic 				}
658*37426Sbostic 		else	stkey = SLET;
659*37426Sbostic 		}
660*37426Sbostic /* otherwise search for keyword */
661*37426Sbostic 	else	{
662*37426Sbostic 		stkey = getkwd();
663*37426Sbostic 		if(stkey==SGOTO && lastch>=nextch)
664*37426Sbostic 			if(nextch[0]=='(')
665*37426Sbostic 				stkey = SCOMPGOTO;
666*37426Sbostic 			else if(isalpha(nextch[0]))
667*37426Sbostic 				stkey = SASGOTO;
668*37426Sbostic 		}
669*37426Sbostic 	parlev = 0;
670*37426Sbostic }
671*37426Sbostic 
672*37426Sbostic 
673*37426Sbostic 
674*37426Sbostic LOCAL getkwd()
675*37426Sbostic {
676*37426Sbostic register char *i, *j;
677*37426Sbostic register struct Keylist *pk, *pend;
678*37426Sbostic int k;
679*37426Sbostic 
680*37426Sbostic if(! isalpha(nextch[0]) )
681*37426Sbostic 	return(SUNKNOWN);
682*37426Sbostic k = nextch[0] - 'a';
683*37426Sbostic if(pk = keystart[k])
684*37426Sbostic 	for(pend = keyend[k] ; pk<=pend ; ++pk )
685*37426Sbostic 		{
686*37426Sbostic 		i = pk->keyname;
687*37426Sbostic 		j = nextch;
688*37426Sbostic 		while(*++i==*++j && *i!='\0')
689*37426Sbostic 			;
690*37426Sbostic 		if(*i=='\0' && j<=lastch+1)
691*37426Sbostic 			{
692*37426Sbostic 			nextch = j;
693*37426Sbostic 			if(no66flag && pk->notinf66)
694*37426Sbostic 				errstr("Not a Fortran 66 keyword: %s",
695*37426Sbostic 					pk->keyname);
696*37426Sbostic 			return(pk->keyval);
697*37426Sbostic 			}
698*37426Sbostic 		}
699*37426Sbostic return(SUNKNOWN);
700*37426Sbostic }
701*37426Sbostic 
702*37426Sbostic 
703*37426Sbostic 
704*37426Sbostic initkey()
705*37426Sbostic {
706*37426Sbostic extern struct Keylist keys[];
707*37426Sbostic register struct Keylist *p;
708*37426Sbostic register int i,j;
709*37426Sbostic 
710*37426Sbostic for(i = 0 ; i<26 ; ++i)
711*37426Sbostic 	keystart[i] = NULL;
712*37426Sbostic 
713*37426Sbostic for(p = keys ; p->keyname ; ++p)
714*37426Sbostic 	{
715*37426Sbostic 	j = p->keyname[0] - 'a';
716*37426Sbostic 	if(keystart[j] == NULL)
717*37426Sbostic 		keystart[j] = p;
718*37426Sbostic 	keyend[j] = p;
719*37426Sbostic 	}
720*37426Sbostic }
721*37426Sbostic 
722*37426Sbostic LOCAL gettok()
723*37426Sbostic {
724*37426Sbostic int havdot, havexp, havdbl;
725*37426Sbostic int radix, val;
726*37426Sbostic extern struct Punctlist puncts[];
727*37426Sbostic struct Punctlist *pp;
728*37426Sbostic extern struct Fmtlist fmts[];
729*37426Sbostic extern struct Dotlist dots[];
730*37426Sbostic struct Dotlist *pd;
731*37426Sbostic 
732*37426Sbostic char *i, *j, *n1, *p;
733*37426Sbostic 
734*37426Sbostic 	if(*nextch == (MYQUOTE))
735*37426Sbostic 		{
736*37426Sbostic 		++nextch;
737*37426Sbostic 		p = token;
738*37426Sbostic 		while(*nextch != MYQUOTE)
739*37426Sbostic 			*p++ = *nextch++;
740*37426Sbostic 		++nextch;
741*37426Sbostic 		toklen = p - token;
742*37426Sbostic 		*p = '\0';
743*37426Sbostic 		return (SHOLLERITH);
744*37426Sbostic 		}
745*37426Sbostic /*
746*37426Sbostic 	if(stkey == SFORMAT)
747*37426Sbostic 		{
748*37426Sbostic 		for(pf = fmts; pf->fmtchar; ++pf)
749*37426Sbostic 			{
750*37426Sbostic 			if(*nextch == pf->fmtchar)
751*37426Sbostic 				{
752*37426Sbostic 				++nextch;
753*37426Sbostic 				if(pf->fmtval == SLPAR)
754*37426Sbostic 					++parlev;
755*37426Sbostic 				else if(pf->fmtval == SRPAR)
756*37426Sbostic 					--parlev;
757*37426Sbostic 				return(pf->fmtval);
758*37426Sbostic 				}
759*37426Sbostic 			}
760*37426Sbostic 		if( isdigit(*nextch) )
761*37426Sbostic 			{
762*37426Sbostic 			p = token;
763*37426Sbostic 			*p++ = *nextch++;
764*37426Sbostic 			while(nextch<=lastch && isdigit(*nextch) )
765*37426Sbostic 				*p++ = *nextch++;
766*37426Sbostic 			toklen = p - token;
767*37426Sbostic 			*p = '\0';
768*37426Sbostic 			if(nextch<=lastch && *nextch=='p')
769*37426Sbostic 				{
770*37426Sbostic 				++nextch;
771*37426Sbostic 				return(SSCALE);
772*37426Sbostic 				}
773*37426Sbostic 			else	return(SICON);
774*37426Sbostic 			}
775*37426Sbostic 		if( isalpha(*nextch) )
776*37426Sbostic 			{
777*37426Sbostic 			p = token;
778*37426Sbostic 			*p++ = *nextch++;
779*37426Sbostic 			while(nextch<=lastch &&
780*37426Sbostic 				(*nextch=='.' || isdigit(*nextch) || isalpha(*nextch) ))
781*37426Sbostic 					*p++ = *nextch++;
782*37426Sbostic 			toklen = p - token;
783*37426Sbostic 			*p = '\0';
784*37426Sbostic 			return(SFIELD);
785*37426Sbostic 			}
786*37426Sbostic 		goto badchar;
787*37426Sbostic 		}
788*37426Sbostic /* Not a format statement */
789*37426Sbostic 
790*37426Sbostic if(needkwd)
791*37426Sbostic 	{
792*37426Sbostic 	needkwd = 0;
793*37426Sbostic 	return( getkwd() );
794*37426Sbostic 	}
795*37426Sbostic 
796*37426Sbostic 	for(pp=puncts; pp->punchar; ++pp)
797*37426Sbostic 		if(*nextch == pp->punchar)
798*37426Sbostic 			{
799*37426Sbostic 			if( (*nextch=='*' || *nextch=='/') &&
800*37426Sbostic 				nextch<lastch && nextch[1]==nextch[0])
801*37426Sbostic 					{
802*37426Sbostic 					if(*nextch == '*')
803*37426Sbostic 						val = SPOWER;
804*37426Sbostic 					else	val = SCONCAT;
805*37426Sbostic 					nextch+=2;
806*37426Sbostic 					}
807*37426Sbostic 			else	{
808*37426Sbostic 				val = pp->punval;
809*37426Sbostic 				if(val==SLPAR)
810*37426Sbostic 					++parlev;
811*37426Sbostic 				else if(val==SRPAR)
812*37426Sbostic 					--parlev;
813*37426Sbostic 				++nextch;
814*37426Sbostic 				}
815*37426Sbostic 			return(val);
816*37426Sbostic 			}
817*37426Sbostic 	if(*nextch == '.')
818*37426Sbostic 		if(nextch >= lastch) goto badchar;
819*37426Sbostic 		else if(isdigit(nextch[1])) goto numconst;
820*37426Sbostic 		else	{
821*37426Sbostic 			for(pd=dots ; (j=pd->dotname) ; ++pd)
822*37426Sbostic 				{
823*37426Sbostic 				for(i=nextch+1 ; i<=lastch ; ++i)
824*37426Sbostic 					if(*i != *j) break;
825*37426Sbostic 					else if(*i != '.') ++j;
826*37426Sbostic 					else	{
827*37426Sbostic 						nextch = i+1;
828*37426Sbostic 						return(pd->dotval);
829*37426Sbostic 						}
830*37426Sbostic 				}
831*37426Sbostic 			goto badchar;
832*37426Sbostic 			}
833*37426Sbostic 	if( isalpha(*nextch) )
834*37426Sbostic 		{
835*37426Sbostic 		p = token;
836*37426Sbostic 		*p++ = *nextch++;
837*37426Sbostic 		while(nextch<=lastch)
838*37426Sbostic 			if( isalpha(*nextch) || isdigit(*nextch) )
839*37426Sbostic 				*p++ = *nextch++;
840*37426Sbostic 			else break;
841*37426Sbostic 		toklen = p - token;
842*37426Sbostic 		*p = '\0';
843*37426Sbostic 		if(inioctl && nextch<=lastch && *nextch=='=')
844*37426Sbostic 			{
845*37426Sbostic 			++nextch;
846*37426Sbostic 			return(SNAMEEQ);
847*37426Sbostic 			}
848*37426Sbostic 		if(toklen>8 && eqn(8,token,"function") && isalpha(token[8]) &&
849*37426Sbostic 			nextch<lastch && nextch[0]=='(' &&
850*37426Sbostic 			(nextch[1]==')' | isalpha(nextch[1])) )
851*37426Sbostic 				{
852*37426Sbostic 				nextch -= (toklen - 8);
853*37426Sbostic 				return(SFUNCTION);
854*37426Sbostic 				}
855*37426Sbostic 		if(toklen > VL)
856*37426Sbostic 			{
857*37426Sbostic 			char buff[30];
858*37426Sbostic 			sprintf(buff, "name %s too long, truncated to %d",
859*37426Sbostic 				token, VL);
860*37426Sbostic 			err(buff);
861*37426Sbostic 			toklen = VL;
862*37426Sbostic 			token[VL] = '\0';
863*37426Sbostic 			}
864*37426Sbostic 		if(toklen==1 && *nextch==MYQUOTE)
865*37426Sbostic 			{
866*37426Sbostic 			switch(token[0])
867*37426Sbostic 				{
868*37426Sbostic 				case 'z':  case 'Z':
869*37426Sbostic 				case 'x':  case 'X':
870*37426Sbostic 					radix = 16; break;
871*37426Sbostic 				case 'o':  case 'O':
872*37426Sbostic 					radix = 8; break;
873*37426Sbostic 				case 'b':  case 'B':
874*37426Sbostic 					radix = 2; break;
875*37426Sbostic 				default:
876*37426Sbostic 					err("bad bit identifier");
877*37426Sbostic 					return(SNAME);
878*37426Sbostic 				}
879*37426Sbostic 			++nextch;
880*37426Sbostic 			for(p = token ; *nextch!=MYQUOTE ; )
881*37426Sbostic 				if ( *nextch == BLANK || *nextch == '\t')
882*37426Sbostic 					nextch++;
883*37426Sbostic 				else
884*37426Sbostic 					{
885*37426Sbostic 					if (isupper(*nextch))
886*37426Sbostic 						*nextch = tolower(*nextch);
887*37426Sbostic 					if (hextoi(*p++ = *nextch++) >= radix)
888*37426Sbostic 						{
889*37426Sbostic 						err("invalid binary character");
890*37426Sbostic 						break;
891*37426Sbostic 						}
892*37426Sbostic 					}
893*37426Sbostic 			++nextch;
894*37426Sbostic 			toklen = p - token;
895*37426Sbostic 			return( radix==16 ? SHEXCON :
896*37426Sbostic 				(radix==8 ? SOCTCON : SBITCON) );
897*37426Sbostic 			}
898*37426Sbostic 		return(SNAME);
899*37426Sbostic 		}
900*37426Sbostic 	if( ! isdigit(*nextch) ) goto badchar;
901*37426Sbostic numconst:
902*37426Sbostic 	havdot = NO;
903*37426Sbostic 	havexp = NO;
904*37426Sbostic 	havdbl = NO;
905*37426Sbostic 	for(n1 = nextch ; nextch<=lastch ; ++nextch)
906*37426Sbostic 		{
907*37426Sbostic 		if(*nextch == '.')
908*37426Sbostic 			if(havdot) break;
909*37426Sbostic 			else if(nextch+2<=lastch && isalpha(nextch[1])
910*37426Sbostic 				&& isalpha(nextch[2]))
911*37426Sbostic 					break;
912*37426Sbostic 			else	havdot = YES;
913*37426Sbostic 		else if( !intonly && (*nextch=='d' || *nextch=='e') )
914*37426Sbostic 			{
915*37426Sbostic 			p = nextch;
916*37426Sbostic 			havexp = YES;
917*37426Sbostic 			if(*nextch == 'd')
918*37426Sbostic 				havdbl = YES;
919*37426Sbostic 			if(nextch<lastch)
920*37426Sbostic 				if(nextch[1]=='+' || nextch[1]=='-')
921*37426Sbostic 					++nextch;
922*37426Sbostic 			if( (nextch >= lastch) || ! isdigit(*++nextch) )
923*37426Sbostic 				{
924*37426Sbostic 				nextch = p;
925*37426Sbostic 				havdbl = havexp = NO;
926*37426Sbostic 				break;
927*37426Sbostic 				}
928*37426Sbostic 			for(++nextch ;
929*37426Sbostic 				nextch<=lastch && isdigit(*nextch);
930*37426Sbostic 				++nextch);
931*37426Sbostic 			break;
932*37426Sbostic 			}
933*37426Sbostic 		else if( ! isdigit(*nextch) )
934*37426Sbostic 			break;
935*37426Sbostic 		}
936*37426Sbostic 	p = token;
937*37426Sbostic 	i = n1;
938*37426Sbostic 	while(i < nextch)
939*37426Sbostic 		*p++ = *i++;
940*37426Sbostic 	toklen = p - token;
941*37426Sbostic 	*p = '\0';
942*37426Sbostic 	if(havdbl) return(SDCON);
943*37426Sbostic 	if(havdot || havexp) return(SRCON);
944*37426Sbostic 	return(SICON);
945*37426Sbostic badchar:
946*37426Sbostic 	s[0] = *nextch++;
947*37426Sbostic 	return(SUNKNOWN);
948*37426Sbostic }
949*37426Sbostic 
950*37426Sbostic /* KEYWORD AND SPECIAL CHARACTER TABLES
951*37426Sbostic */
952*37426Sbostic 
953*37426Sbostic struct Punctlist puncts[ ] =
954*37426Sbostic 	{
955*37426Sbostic 	'(', SLPAR,
956*37426Sbostic 	')', SRPAR,
957*37426Sbostic 	'=', SEQUALS,
958*37426Sbostic 	',', SCOMMA,
959*37426Sbostic 	'+', SPLUS,
960*37426Sbostic 	'-', SMINUS,
961*37426Sbostic 	'*', SSTAR,
962*37426Sbostic 	'/', SSLASH,
963*37426Sbostic 	'$', SCURRENCY,
964*37426Sbostic 	':', SCOLON,
965*37426Sbostic 	0, 0 } ;
966*37426Sbostic 
967*37426Sbostic /*
968*37426Sbostic LOCAL struct Fmtlist  fmts[ ] =
969*37426Sbostic 	{
970*37426Sbostic 	'(', SLPAR,
971*37426Sbostic 	')', SRPAR,
972*37426Sbostic 	'/', SSLASH,
973*37426Sbostic 	',', SCOMMA,
974*37426Sbostic 	'-', SMINUS,
975*37426Sbostic 	':', SCOLON,
976*37426Sbostic 	0, 0 } ;
977*37426Sbostic */
978*37426Sbostic 
979*37426Sbostic LOCAL struct Dotlist  dots[ ] =
980*37426Sbostic 	{
981*37426Sbostic 	"and.", SAND,
982*37426Sbostic 	"or.", SOR,
983*37426Sbostic 	"not.", SNOT,
984*37426Sbostic 	"true.", STRUE,
985*37426Sbostic 	"false.", SFALSE,
986*37426Sbostic 	"eq.", SEQ,
987*37426Sbostic 	"ne.", SNE,
988*37426Sbostic 	"lt.", SLT,
989*37426Sbostic 	"le.", SLE,
990*37426Sbostic 	"gt.", SGT,
991*37426Sbostic 	"ge.", SGE,
992*37426Sbostic 	"neqv.", SNEQV,
993*37426Sbostic 	"eqv.", SEQV,
994*37426Sbostic 	0, 0 } ;
995*37426Sbostic 
996*37426Sbostic LOCAL struct Keylist  keys[ ] =
997*37426Sbostic 	{
998*37426Sbostic 	 	{ "assign",  SASSIGN  },
999*37426Sbostic 	 	{ "automatic",  SAUTOMATIC, YES  },
1000*37426Sbostic 	 	{ "backspace",  SBACKSPACE  },
1001*37426Sbostic 	 	{ "blockdata",  SBLOCK  },
1002*37426Sbostic 	 	{ "call",  SCALL  },
1003*37426Sbostic 	 	{ "character",  SCHARACTER, YES  },
1004*37426Sbostic 	 	{ "close",  SCLOSE, YES  },
1005*37426Sbostic 	 	{ "common",  SCOMMON  },
1006*37426Sbostic 	 	{ "complex",  SCOMPLEX  },
1007*37426Sbostic 	 	{ "continue",  SCONTINUE  },
1008*37426Sbostic 	 	{ "data",  SDATA  },
1009*37426Sbostic 	 	{ "dimension",  SDIMENSION  },
1010*37426Sbostic 	 	{ "doubleprecision",  SDOUBLE  },
1011*37426Sbostic 	 	{ "doublecomplex", SDCOMPLEX, YES  },
1012*37426Sbostic 	 	{ "elseif",  SELSEIF, YES  },
1013*37426Sbostic 	 	{ "else",  SELSE, YES  },
1014*37426Sbostic 	 	{ "endfile",  SENDFILE  },
1015*37426Sbostic 	 	{ "endif",  SENDIF, YES  },
1016*37426Sbostic 	 	{ "end",  SEND  },
1017*37426Sbostic 	 	{ "entry",  SENTRY, YES  },
1018*37426Sbostic 	 	{ "equivalence",  SEQUIV  },
1019*37426Sbostic 	 	{ "external",  SEXTERNAL  },
1020*37426Sbostic 	 	{ "format",  SFORMAT  },
1021*37426Sbostic 	 	{ "function",  SFUNCTION  },
1022*37426Sbostic 	 	{ "goto",  SGOTO  },
1023*37426Sbostic 	 	{ "implicit",  SIMPLICIT, YES  },
1024*37426Sbostic 	 	{ "include",  SINCLUDE, YES  },
1025*37426Sbostic 	 	{ "inquire",  SINQUIRE, YES  },
1026*37426Sbostic 	 	{ "intrinsic",  SINTRINSIC, YES  },
1027*37426Sbostic 	 	{ "integer",  SINTEGER  },
1028*37426Sbostic 	 	{ "logical",  SLOGICAL  },
1029*37426Sbostic #ifdef NAMELIST
1030*37426Sbostic 		{ "namelist", SNAMELIST, YES },
1031*37426Sbostic #endif
1032*37426Sbostic 		{ "none", SUNDEFINED, YES },
1033*37426Sbostic 	 	{ "open",  SOPEN, YES  },
1034*37426Sbostic 	 	{ "parameter",  SPARAM, YES  },
1035*37426Sbostic 	 	{ "pause",  SPAUSE  },
1036*37426Sbostic 	 	{ "print",  SPRINT  },
1037*37426Sbostic 	 	{ "program",  SPROGRAM, YES  },
1038*37426Sbostic 	 	{ "punch",  SPUNCH, YES  },
1039*37426Sbostic 	 	{ "read",  SREAD  },
1040*37426Sbostic 	 	{ "real",  SREAL  },
1041*37426Sbostic 	 	{ "return",  SRETURN  },
1042*37426Sbostic 	 	{ "rewind",  SREWIND  },
1043*37426Sbostic 	 	{ "save",  SSAVE, YES  },
1044*37426Sbostic 	 	{ "static",  SSTATIC, YES  },
1045*37426Sbostic 	 	{ "stop",  SSTOP  },
1046*37426Sbostic 	 	{ "subroutine",  SSUBROUTINE  },
1047*37426Sbostic 	 	{ "then",  STHEN, YES  },
1048*37426Sbostic 	 	{ "undefined", SUNDEFINED, YES  },
1049*37426Sbostic 	 	{ "write",  SWRITE  },
1050*37426Sbostic 			{ 0, 0 }
1051*37426Sbostic 	};
1052