xref: /csrg-svn/usr.bin/f77/libI77/fmt.c (revision 2508)
1*2508Sdlw /*
2*2508Sdlw char id_fmt[] = "@(#)fmt.c	1.1";
3*2508Sdlw  *
4*2508Sdlw  * fortran format parser
5*2508Sdlw  */
6*2508Sdlw 
7*2508Sdlw #include "fio.h"
8*2508Sdlw #include "fmt.h"
9*2508Sdlw 
10*2508Sdlw #define isdigit(x)	(x>='0' && x<='9')
11*2508Sdlw #define isspace(s)	(s==' ')
12*2508Sdlw #define skip(s)		while(isspace(*s)) s++
13*2508Sdlw 
14*2508Sdlw #ifdef interdata
15*2508Sdlw #define SYLMX 300
16*2508Sdlw #endif
17*2508Sdlw 
18*2508Sdlw #ifdef pdp11
19*2508Sdlw #define SYLMX 300
20*2508Sdlw #endif
21*2508Sdlw 
22*2508Sdlw #ifdef vax
23*2508Sdlw #define SYLMX 300
24*2508Sdlw #endif
25*2508Sdlw 
26*2508Sdlw struct syl syl[SYLMX];
27*2508Sdlw int parenlvl,pc,revloc;
28*2508Sdlw char *f_s(), *f_list(), *i_tem(), *gt_num(), *ap_end();
29*2508Sdlw 
30*2508Sdlw pars_f(s) char *s;
31*2508Sdlw {
32*2508Sdlw 	parenlvl=revloc=pc=0;
33*2508Sdlw 	return((f_s(s,0)==FMTERR)? ERROR : OK);
34*2508Sdlw }
35*2508Sdlw 
36*2508Sdlw char *f_s(s,curloc) char *s;
37*2508Sdlw {
38*2508Sdlw 	skip(s);
39*2508Sdlw 	if(*s++!='(')
40*2508Sdlw 	{
41*2508Sdlw 		fmtptr = s;
42*2508Sdlw 		return(FMTERR);
43*2508Sdlw 	}
44*2508Sdlw 	if(parenlvl++ ==1) revloc=curloc;
45*2508Sdlw 	op_gen(RET,curloc,0,0,s);
46*2508Sdlw 	if((s=f_list(s))==FMTERR)
47*2508Sdlw 	{
48*2508Sdlw 		return(FMTERR);
49*2508Sdlw 	}
50*2508Sdlw 	skip(s);
51*2508Sdlw 	return(s);
52*2508Sdlw }
53*2508Sdlw 
54*2508Sdlw char *f_list(s) char *s;
55*2508Sdlw {
56*2508Sdlw 	while (*s)
57*2508Sdlw 	{	skip(s);
58*2508Sdlw 		if((s=i_tem(s))==FMTERR) return(FMTERR);
59*2508Sdlw 		skip(s);
60*2508Sdlw 		if(*s==',') s++;
61*2508Sdlw 		else if(*s==')')
62*2508Sdlw 		{	if(--parenlvl==0)
63*2508Sdlw 			{
64*2508Sdlw 				op_gen(REVERT,revloc,0,0,s);
65*2508Sdlw 			}
66*2508Sdlw 			else	op_gen(GOTO,0,0,0,s);
67*2508Sdlw 			return(++s);
68*2508Sdlw 		}
69*2508Sdlw 	}
70*2508Sdlw 	fmtptr = s;
71*2508Sdlw 	return(FMTERR);
72*2508Sdlw }
73*2508Sdlw 
74*2508Sdlw char *i_tem(s) char *s;
75*2508Sdlw {	char *t;
76*2508Sdlw 	int n,curloc;
77*2508Sdlw 	if(*s==')') return(s);
78*2508Sdlw 	if(ne_d(s,&t)) return(t);
79*2508Sdlw 	if(e_d(s,&t)) return(t);
80*2508Sdlw 	s=gt_num(s,&n);
81*2508Sdlw 	curloc = op_gen(STACK,n,0,0,s);
82*2508Sdlw 	return(f_s(s,curloc));
83*2508Sdlw }
84*2508Sdlw 
85*2508Sdlw ne_d(s,p) char *s,**p;
86*2508Sdlw {	int n,x,sign=0,pp1,pp2;
87*2508Sdlw 	switch(lcase(*s))
88*2508Sdlw 	{
89*2508Sdlw 	case ':': op_gen(COLON,(int)('\n'),0,0,s); break;
90*2508Sdlw #ifndef KOSHER
91*2508Sdlw 	case '$': op_gen(DOLAR,(int)('\0'),0,0,s); break;  /*** NOT STANDARD FORTRAN ***/
92*2508Sdlw #endif
93*2508Sdlw 	case 'b':
94*2508Sdlw 		switch(lcase(*(s+1)))
95*2508Sdlw 		{
96*2508Sdlw 			case 'z': s++; op_gen(BZ,1,0,0,s); break;
97*2508Sdlw 			case 'n': s++;
98*2508Sdlw 			default:  op_gen(BN,0,0,0,s); break;
99*2508Sdlw 		}
100*2508Sdlw 		break;
101*2508Sdlw 	case 's':
102*2508Sdlw 		switch(lcase(*(s+1)))
103*2508Sdlw 		{
104*2508Sdlw 			case 'p': s++; x=SP; pp1=1; pp2=1; break;
105*2508Sdlw #ifndef KOSHER
106*2508Sdlw 			case 'u': s++; x=SU; pp1=0; pp2=0; break;  /*** NOT STANDARD FORTRAN ***/
107*2508Sdlw #endif
108*2508Sdlw 			case 's': s++; x=SS; pp1=0; pp2=1; break;
109*2508Sdlw 			default:  x=S; pp1=0; pp2=1; break;
110*2508Sdlw 		}
111*2508Sdlw 		op_gen(x,pp1,pp2,0,s);
112*2508Sdlw 		break;
113*2508Sdlw 	case '/': op_gen(SLASH,0,0,0,s); break;
114*2508Sdlw 	case '-': sign=1; s++;	/*OUTRAGEOUS CODING TRICK*/
115*2508Sdlw 	case '0': case '1': case '2': case '3': case '4':
116*2508Sdlw 	case '5': case '6': case '7': case '8': case '9':
117*2508Sdlw 		s=gt_num(s,&n);
118*2508Sdlw 		switch(lcase(*s))
119*2508Sdlw 		{
120*2508Sdlw 		case 'p': if(sign) n= -n; op_gen(P,n,0,0,s); break;
121*2508Sdlw #ifndef KOSHER
122*2508Sdlw 		case 'r': if(n<=1)		/*** NOT STANDARD FORTRAN ***/
123*2508Sdlw 			{	fmtptr = s; return(FMTERR); }
124*2508Sdlw 			op_gen(R,n,0,0,s); break;
125*2508Sdlw 		case 't': op_gen(T,0,n,0,s); break;	/* NOT STANDARD FORT */
126*2508Sdlw #endif
127*2508Sdlw 		case 'x': op_gen(X,n,0,0,s); break;
128*2508Sdlw 		case 'h': op_gen(H,n,(int)(s+1),0,s);
129*2508Sdlw 			s+=n;
130*2508Sdlw 			break;
131*2508Sdlw 		default: fmtptr = s; return(0);
132*2508Sdlw 		}
133*2508Sdlw 		break;
134*2508Sdlw 	case GLITCH:
135*2508Sdlw 	case '"':
136*2508Sdlw 	case '\'': op_gen(APOS,(int)s,0,0,s);
137*2508Sdlw 		*p = ap_end(s);
138*2508Sdlw 		return(FMTOK);
139*2508Sdlw 	case 't':
140*2508Sdlw 		switch(lcase(*(s+1)))
141*2508Sdlw 		{
142*2508Sdlw 			case 'l': s++; x=TL; break;
143*2508Sdlw 			case 'r': s++; x=TR; break;
144*2508Sdlw 			default:  x=T; break;
145*2508Sdlw 		}
146*2508Sdlw 		if(isdigit(*(s+1))) {s=gt_num(s+1,&n); s--;}
147*2508Sdlw #ifndef KOSHER
148*2508Sdlw 		else n = 0;	/* NOT STANDARD FORTRAN, should be error */
149*2508Sdlw #endif
150*2508Sdlw #ifdef KOSHER
151*2508Sdlw 		fmtptr = s; return(FMTERR);
152*2508Sdlw #endif
153*2508Sdlw 		op_gen(x,n,1,0,s);
154*2508Sdlw 		break;
155*2508Sdlw 	case 'x': op_gen(X,1,0,0,s); break;
156*2508Sdlw 	case 'p': op_gen(P,0,0,0,s); break;
157*2508Sdlw #ifndef KOSHER
158*2508Sdlw 	case 'r': op_gen(R,10,1,0,s); break;  /*** NOT STANDARD FORTRAN ***/
159*2508Sdlw #endif
160*2508Sdlw 
161*2508Sdlw 	default: fmtptr = s; return(0);
162*2508Sdlw 	}
163*2508Sdlw 	s++;
164*2508Sdlw 	*p=s;
165*2508Sdlw 	return(FMTOK);
166*2508Sdlw }
167*2508Sdlw 
168*2508Sdlw e_d(s,p) char *s,**p;
169*2508Sdlw {	int n,w,d,e,x=0;
170*2508Sdlw 	char *sv=s;
171*2508Sdlw 	char c;
172*2508Sdlw 	s=gt_num(s,&n);
173*2508Sdlw 	op_gen(STACK,n,0,0,s);
174*2508Sdlw 	c = lcase(*s); s++;
175*2508Sdlw 	switch(c)
176*2508Sdlw 	{
177*2508Sdlw 	case 'd':
178*2508Sdlw 	case 'e':
179*2508Sdlw 	case 'g':
180*2508Sdlw 		s = gt_num(s, &w);
181*2508Sdlw 		if (w==0) break;
182*2508Sdlw 		if(*s=='.')
183*2508Sdlw 		{	s++;
184*2508Sdlw 			s=gt_num(s,&d);
185*2508Sdlw 		}
186*2508Sdlw 		else d=0;
187*2508Sdlw 		if(lcase(*s) == 'e'
188*2508Sdlw #ifndef KOSHER
189*2508Sdlw 		|| *s == '.'		 /*** '.' is NOT STANDARD FORTRAN ***/
190*2508Sdlw #endif
191*2508Sdlw 		)
192*2508Sdlw 		{	s++;
193*2508Sdlw 			s=gt_num(s,&e);
194*2508Sdlw 			if(c=='e') n=EE; else if(c=='d') n=DE; else n=GE;
195*2508Sdlw 		}
196*2508Sdlw 		else
197*2508Sdlw 		{	e=2;
198*2508Sdlw 			if(c=='e') n=E; else if(c=='d') n=D; else n=G;
199*2508Sdlw 		}
200*2508Sdlw 		op_gen(n,w,d,e,s);
201*2508Sdlw 		break;
202*2508Sdlw 	case 'l':
203*2508Sdlw 		s = gt_num(s, &w);
204*2508Sdlw 		if (w==0) break;
205*2508Sdlw 		op_gen(L,w,0,0,s);
206*2508Sdlw 		break;
207*2508Sdlw 	case 'a':
208*2508Sdlw 		skip(s);
209*2508Sdlw 		if(*s>='0' && *s<='9')
210*2508Sdlw 		{	s=gt_num(s,&w);
211*2508Sdlw 			if(w==0) break;
212*2508Sdlw 			op_gen(AW,w,0,0,s);
213*2508Sdlw 			break;
214*2508Sdlw 		}
215*2508Sdlw 		op_gen(A,0,0,0,s);
216*2508Sdlw 		break;
217*2508Sdlw 	case 'f':
218*2508Sdlw 		s = gt_num(s, &w);
219*2508Sdlw 		if (w==0) break;
220*2508Sdlw 		if(*s=='.')
221*2508Sdlw 		{	s++;
222*2508Sdlw 			s=gt_num(s,&d);
223*2508Sdlw 		}
224*2508Sdlw 		else d=0;
225*2508Sdlw 		op_gen(F,w,d,0,s);
226*2508Sdlw 		break;
227*2508Sdlw 	case 'i':
228*2508Sdlw 		s = gt_num(s, &w);
229*2508Sdlw 		if (w==0) break;
230*2508Sdlw 		if(*s =='.')
231*2508Sdlw 		{
232*2508Sdlw 			s++;
233*2508Sdlw 			s=gt_num(s,&d);
234*2508Sdlw 			x = IM;
235*2508Sdlw 		}
236*2508Sdlw 		else
237*2508Sdlw 		{	d = 1;
238*2508Sdlw 			x = I;
239*2508Sdlw 		}
240*2508Sdlw 		op_gen(x,w,d,0,s);
241*2508Sdlw 		break;
242*2508Sdlw 	default:
243*2508Sdlw 		pc--;	/* unSTACK */
244*2508Sdlw 		*p = sv;
245*2508Sdlw 		fmtptr = s;
246*2508Sdlw 		return(FMTERR);
247*2508Sdlw 	}
248*2508Sdlw 	*p = s;
249*2508Sdlw 	return(FMTOK);
250*2508Sdlw }
251*2508Sdlw 
252*2508Sdlw op_gen(a,b,c,d,s) char *s;
253*2508Sdlw {	struct syl *p= &syl[pc];
254*2508Sdlw 	if(pc>=SYLMX)
255*2508Sdlw 	{	fmtptr = s;
256*2508Sdlw 		fatal(100,"format too complex");
257*2508Sdlw 	}
258*2508Sdlw #ifdef DEBUG
259*2508Sdlw 	fprintf(stderr,"%3d opgen: %d %d %d %d %c\n",
260*2508Sdlw 		pc,a,b,c,d,*s==GLITCH?'"':*s); /* for debug */
261*2508Sdlw #endif
262*2508Sdlw 	p->op=a;
263*2508Sdlw 	p->p1=b;
264*2508Sdlw 	p->p2=c;
265*2508Sdlw 	p->p3=d;
266*2508Sdlw 	return(pc++);
267*2508Sdlw }
268*2508Sdlw 
269*2508Sdlw char *gt_num(s,n) char *s; int *n;
270*2508Sdlw {	int m=0,a_digit=NO;
271*2508Sdlw 	skip(s);
272*2508Sdlw 	while(isdigit(*s) || isspace(*s))
273*2508Sdlw 	{
274*2508Sdlw 		if (isdigit(*s))
275*2508Sdlw 		{
276*2508Sdlw 			m = 10*m + (*s)-'0';
277*2508Sdlw 			a_digit = YES;
278*2508Sdlw 		}
279*2508Sdlw 		s++;
280*2508Sdlw 	}
281*2508Sdlw 	if(a_digit) *n=m;
282*2508Sdlw 	else *n=1;
283*2508Sdlw 	return(s);
284*2508Sdlw }
285*2508Sdlw 
286*2508Sdlw char *ap_end(s) char *s;
287*2508Sdlw {
288*2508Sdlw 	char quote;
289*2508Sdlw 	quote = *s++;
290*2508Sdlw 	for(;*s;s++)
291*2508Sdlw 	{
292*2508Sdlw 		if(*s==quote && *++s!=quote) return(s);
293*2508Sdlw 	}
294*2508Sdlw 	fmtptr = s;
295*2508Sdlw 	fatal(100,"bad string");
296*2508Sdlw }
297