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