137426Sbostic /* 237426Sbostic * Copyright (c) 1980 Regents of the University of California. 337426Sbostic * All rights reserved. The Berkeley software License Agreement 437426Sbostic * specifies the terms and conditions for redistribution. 537426Sbostic */ 637426Sbostic 737426Sbostic #ifndef lint 837426Sbostic static char sccsid[] = "@(#)lex.c 5.1 (Berkeley) 6/7/85"; 937426Sbostic #endif not lint 1037426Sbostic 1137426Sbostic /* 1237426Sbostic * lex.c 1337426Sbostic * 1437426Sbostic * Lexical scanner routines for the f77 compiler, pass 1, 4.2 BSD. 1537426Sbostic * 1637426Sbostic * University of Utah CS Dept modification history: 1737426Sbostic * 1837426Sbostic * $Log: lex.c,v $ 1937426Sbostic * Revision 1.2 84/10/27 02:20:09 donn 2037426Sbostic * Fixed bug where the input file and the name field of the include file 2137426Sbostic * structure shared -- when the input file name was freed, the include file 2237426Sbostic * name got stomped on, leading to peculiar error messages. 2337426Sbostic * 2437426Sbostic */ 2537426Sbostic 2637426Sbostic #include "defs.h" 2737426Sbostic #include "tokdefs.h" 28*37793Sbostic #include "pathnames.h" 2937426Sbostic 3037426Sbostic # define BLANK ' ' 3137426Sbostic # define MYQUOTE (2) 3237426Sbostic # define SEOF 0 3337426Sbostic 3437426Sbostic /* card types */ 3537426Sbostic 3637426Sbostic # define STEOF 1 3737426Sbostic # define STINITIAL 2 3837426Sbostic # define STCONTINUE 3 3937426Sbostic 4037426Sbostic /* lex states */ 4137426Sbostic 4237426Sbostic #define NEWSTMT 1 4337426Sbostic #define FIRSTTOKEN 2 4437426Sbostic #define OTHERTOKEN 3 4537426Sbostic #define RETEOS 4 4637426Sbostic 4737426Sbostic 4837426Sbostic LOCAL int stkey; 4937426Sbostic LOCAL int lastend = 1; 5037426Sbostic ftnint yystno; 5137426Sbostic flag intonly; 5237426Sbostic LOCAL long int stno; 5337426Sbostic LOCAL long int nxtstno; 5437426Sbostic LOCAL int parlev; 5537426Sbostic LOCAL int expcom; 5637426Sbostic LOCAL int expeql; 5737426Sbostic LOCAL char *nextch; 5837426Sbostic LOCAL char *lastch; 5937426Sbostic LOCAL char *nextcd = NULL; 6037426Sbostic LOCAL char *endcd; 6137426Sbostic LOCAL int prevlin; 6237426Sbostic LOCAL int thislin; 6337426Sbostic LOCAL int code; 6437426Sbostic LOCAL int lexstate = NEWSTMT; 6537426Sbostic LOCAL char s[1390]; 6637426Sbostic LOCAL char *send = s+20*66; 6737426Sbostic LOCAL int nincl = 0; 6837426Sbostic LOCAL char *newname = NULL; 6937426Sbostic 7037426Sbostic struct Inclfile 7137426Sbostic { 7237426Sbostic struct Inclfile *inclnext; 7337426Sbostic FILEP inclfp; 7437426Sbostic char *inclname; 7537426Sbostic int incllno; 7637426Sbostic char *incllinp; 7737426Sbostic int incllen; 7837426Sbostic int inclcode; 7937426Sbostic ftnint inclstno; 8037426Sbostic } ; 8137426Sbostic 8237426Sbostic LOCAL struct Inclfile *inclp = NULL; 8337426Sbostic LOCAL struct Keylist { char *keyname; int keyval; char notinf66; } ; 8437426Sbostic LOCAL struct Punctlist { char punchar; int punval; }; 8537426Sbostic LOCAL struct Fmtlist { char fmtchar; int fmtval; }; 8637426Sbostic LOCAL struct Dotlist { char *dotname; int dotval; }; 8737426Sbostic LOCAL struct Keylist *keystart[26], *keyend[26]; 8837426Sbostic 8937426Sbostic 9037426Sbostic 9137426Sbostic 9237426Sbostic inilex(name) 9337426Sbostic char *name; 9437426Sbostic { 9537426Sbostic nincl = 0; 9637426Sbostic inclp = NULL; 9737426Sbostic doinclude(name); 9837426Sbostic lexstate = NEWSTMT; 9937426Sbostic return(NO); 10037426Sbostic } 10137426Sbostic 10237426Sbostic 10337426Sbostic 10437426Sbostic /* throw away the rest of the current line */ 10537426Sbostic flline() 10637426Sbostic { 10737426Sbostic lexstate = RETEOS; 10837426Sbostic } 10937426Sbostic 11037426Sbostic 11137426Sbostic 11237426Sbostic char *lexline(n) 11337426Sbostic int *n; 11437426Sbostic { 11537426Sbostic *n = (lastch - nextch) + 1; 11637426Sbostic return(nextch); 11737426Sbostic } 11837426Sbostic 11937426Sbostic 12037426Sbostic 12137426Sbostic 12237426Sbostic 12337426Sbostic doinclude(name) 12437426Sbostic char *name; 12537426Sbostic { 12637426Sbostic FILEP fp; 12737426Sbostic struct Inclfile *t; 12837426Sbostic char temp[100]; 12937426Sbostic register char *lastslash, *s; 13037426Sbostic 13137426Sbostic if(inclp) 13237426Sbostic { 13337426Sbostic inclp->incllno = thislin; 13437426Sbostic inclp->inclcode = code; 13537426Sbostic inclp->inclstno = nxtstno; 13637426Sbostic if(nextcd) 13737426Sbostic inclp->incllinp = copyn(inclp->incllen = endcd-nextcd , nextcd); 13837426Sbostic else 13937426Sbostic inclp->incllinp = 0; 14037426Sbostic } 14137426Sbostic nextcd = NULL; 14237426Sbostic 14337426Sbostic if(++nincl >= MAXINCLUDES) 14437426Sbostic fatal("includes nested too deep"); 14537426Sbostic if(name[0] == '\0') 14637426Sbostic fp = stdin; 14737426Sbostic else if(name[0]=='/' || inclp==NULL) 14837426Sbostic fp = fopen(name, "r"); 14937426Sbostic else { 15037426Sbostic lastslash = NULL; 15137426Sbostic for(s = inclp->inclname ; *s ; ++s) 15237426Sbostic if(*s == '/') 15337426Sbostic lastslash = s; 15437426Sbostic if(lastslash) 15537426Sbostic { 15637426Sbostic *lastslash = '\0'; 15737426Sbostic sprintf(temp, "%s/%s", inclp->inclname, name); 15837426Sbostic *lastslash = '/'; 15937426Sbostic } 16037426Sbostic else 16137426Sbostic strcpy(temp, name); 16237426Sbostic 16337426Sbostic if( (fp = fopen(temp, "r")) == NULL ) 16437426Sbostic { 165*37793Sbostic sprintf(temp, "%s/%s", _PATH_INCLUDES, name); 16637426Sbostic fp = fopen(temp, "r"); 16737426Sbostic } 16837426Sbostic if(fp) 16937426Sbostic name = copys(temp); 17037426Sbostic } 17137426Sbostic 17237426Sbostic if( fp ) 17337426Sbostic { 17437426Sbostic t = inclp; 17537426Sbostic inclp = ALLOC(Inclfile); 17637426Sbostic inclp->inclnext = t; 17737426Sbostic prevlin = thislin = 0; 17837426Sbostic inclp->inclname = name; 17937426Sbostic infname = copys(name); 18037426Sbostic infile = inclp->inclfp = fp; 18137426Sbostic } 18237426Sbostic else 18337426Sbostic { 18437426Sbostic fprintf(diagfile, "Cannot open file %s", name); 18537426Sbostic done(1); 18637426Sbostic } 18737426Sbostic } 18837426Sbostic 18937426Sbostic 19037426Sbostic 19137426Sbostic 19237426Sbostic LOCAL popinclude() 19337426Sbostic { 19437426Sbostic struct Inclfile *t; 19537426Sbostic register char *p; 19637426Sbostic register int k; 19737426Sbostic 19837426Sbostic if(infile != stdin) 19937426Sbostic clf(&infile); 20037426Sbostic free(infname); 20137426Sbostic 20237426Sbostic --nincl; 20337426Sbostic t = inclp->inclnext; 20437426Sbostic free(inclp->inclname); 20537426Sbostic free( (charptr) inclp); 20637426Sbostic inclp = t; 20737426Sbostic if(inclp == NULL) 20837426Sbostic return(NO); 20937426Sbostic 21037426Sbostic infile = inclp->inclfp; 21137426Sbostic infname = copys(inclp->inclname); 21237426Sbostic prevlin = thislin = inclp->incllno; 21337426Sbostic code = inclp->inclcode; 21437426Sbostic stno = nxtstno = inclp->inclstno; 21537426Sbostic if(inclp->incllinp) 21637426Sbostic { 21737426Sbostic endcd = nextcd = s; 21837426Sbostic k = inclp->incllen; 21937426Sbostic p = inclp->incllinp; 22037426Sbostic while(--k >= 0) 22137426Sbostic *endcd++ = *p++; 22237426Sbostic free( (charptr) (inclp->incllinp) ); 22337426Sbostic } 22437426Sbostic else 22537426Sbostic nextcd = NULL; 22637426Sbostic return(YES); 22737426Sbostic } 22837426Sbostic 22937426Sbostic 23037426Sbostic 23137426Sbostic 23237426Sbostic yylex() 23337426Sbostic { 23437426Sbostic static int tokno; 23537426Sbostic 23637426Sbostic switch(lexstate) 23737426Sbostic { 23837426Sbostic case NEWSTMT : /* need a new statement */ 23937426Sbostic if(getcds() == STEOF) 24037426Sbostic return(SEOF); 24137426Sbostic lastend = stkey == SEND; 24237426Sbostic crunch(); 24337426Sbostic tokno = 0; 24437426Sbostic lexstate = FIRSTTOKEN; 24537426Sbostic yystno = stno; 24637426Sbostic stno = nxtstno; 24737426Sbostic toklen = 0; 24837426Sbostic return(SLABEL); 24937426Sbostic 25037426Sbostic first: 25137426Sbostic case FIRSTTOKEN : /* first step on a statement */ 25237426Sbostic analyz(); 25337426Sbostic lexstate = OTHERTOKEN; 25437426Sbostic tokno = 1; 25537426Sbostic return(stkey); 25637426Sbostic 25737426Sbostic case OTHERTOKEN : /* return next token */ 25837426Sbostic if(nextch > lastch) 25937426Sbostic goto reteos; 26037426Sbostic ++tokno; 26137426Sbostic if( (stkey==SLOGIF || stkey==SELSEIF) && parlev==0 && tokno>3) 26237426Sbostic goto first; 26337426Sbostic 26437426Sbostic if(stkey==SASSIGN && tokno==3 && nextch<lastch && 26537426Sbostic nextch[0]=='t' && nextch[1]=='o') 26637426Sbostic { 26737426Sbostic nextch+=2; 26837426Sbostic return(STO); 26937426Sbostic } 27037426Sbostic return(gettok()); 27137426Sbostic 27237426Sbostic reteos: 27337426Sbostic case RETEOS: 27437426Sbostic lexstate = NEWSTMT; 27537426Sbostic return(SEOS); 27637426Sbostic } 27737426Sbostic fatali("impossible lexstate %d", lexstate); 27837426Sbostic /* NOTREACHED */ 27937426Sbostic } 28037426Sbostic 28137426Sbostic LOCAL getcds() 28237426Sbostic { 28337426Sbostic register char *p, *q; 28437426Sbostic 28537426Sbostic if (newname) 28637426Sbostic { 28737426Sbostic free(infname); 28837426Sbostic infname = newname; 28937426Sbostic newname = NULL; 29037426Sbostic } 29137426Sbostic 29237426Sbostic top: 29337426Sbostic if(nextcd == NULL) 29437426Sbostic { 29537426Sbostic code = getcd( nextcd = s ); 29637426Sbostic stno = nxtstno; 29737426Sbostic if (newname) 29837426Sbostic { 29937426Sbostic free(infname); 30037426Sbostic infname = newname; 30137426Sbostic newname = NULL; 30237426Sbostic } 30337426Sbostic prevlin = thislin; 30437426Sbostic } 30537426Sbostic if(code == STEOF) 30637426Sbostic if( popinclude() ) 30737426Sbostic goto top; 30837426Sbostic else 30937426Sbostic return(STEOF); 31037426Sbostic 31137426Sbostic if(code == STCONTINUE) 31237426Sbostic { 31337426Sbostic if (newname) 31437426Sbostic { 31537426Sbostic free(infname); 31637426Sbostic infname = newname; 31737426Sbostic newname = NULL; 31837426Sbostic } 31937426Sbostic lineno = thislin; 32037426Sbostic err("illegal continuation card ignored"); 32137426Sbostic nextcd = NULL; 32237426Sbostic goto top; 32337426Sbostic } 32437426Sbostic 32537426Sbostic if(nextcd > s) 32637426Sbostic { 32737426Sbostic q = nextcd; 32837426Sbostic p = s; 32937426Sbostic while(q < endcd) 33037426Sbostic *p++ = *q++; 33137426Sbostic endcd = p; 33237426Sbostic } 33337426Sbostic for(nextcd = endcd ; 33437426Sbostic nextcd+66<=send && (code = getcd(nextcd))==STCONTINUE ; 33537426Sbostic nextcd = endcd ) 33637426Sbostic ; 33737426Sbostic nextch = s; 33837426Sbostic lastch = nextcd - 1; 33937426Sbostic if(nextcd >= send) 34037426Sbostic nextcd = NULL; 34137426Sbostic lineno = prevlin; 34237426Sbostic prevlin = thislin; 34337426Sbostic return(STINITIAL); 34437426Sbostic } 34537426Sbostic 34637426Sbostic LOCAL getcd(b) 34737426Sbostic register char *b; 34837426Sbostic { 34937426Sbostic register int c; 35037426Sbostic register char *p, *bend; 35137426Sbostic int speclin; 35237426Sbostic static char a[6]; 35337426Sbostic static char *aend = a+6; 35437426Sbostic int num; 35537426Sbostic 35637426Sbostic top: 35737426Sbostic endcd = b; 35837426Sbostic bend = b+66; 35937426Sbostic speclin = NO; 36037426Sbostic 36137426Sbostic if( (c = getc(infile)) == '&') 36237426Sbostic { 36337426Sbostic a[0] = BLANK; 36437426Sbostic a[5] = 'x'; 36537426Sbostic speclin = YES; 36637426Sbostic bend = send; 36737426Sbostic } 36837426Sbostic else if(c=='c' || c=='C' || c=='*') 36937426Sbostic { 37037426Sbostic while( (c = getc(infile)) != '\n') 37137426Sbostic if(c == EOF) 37237426Sbostic return(STEOF); 37337426Sbostic ++thislin; 37437426Sbostic goto top; 37537426Sbostic } 37637426Sbostic else if(c == '#') 37737426Sbostic { 37837426Sbostic c = getc(infile); 37937426Sbostic while (c == BLANK || c == '\t') 38037426Sbostic c = getc(infile); 38137426Sbostic 38237426Sbostic num = 0; 38337426Sbostic while (isdigit(c)) 38437426Sbostic { 38537426Sbostic num = 10*num + c - '0'; 38637426Sbostic c = getc(infile); 38737426Sbostic } 38837426Sbostic thislin = num - 1; 38937426Sbostic 39037426Sbostic while (c == BLANK || c == '\t') 39137426Sbostic c = getc(infile); 39237426Sbostic 39337426Sbostic if (c == '"') 39437426Sbostic { 39537426Sbostic char fname[1024]; 39637426Sbostic int len = 0; 39737426Sbostic 39837426Sbostic c = getc(infile); 39937426Sbostic while (c != '"' && c != '\n') 40037426Sbostic { 40137426Sbostic fname[len++] = c; 40237426Sbostic c = getc(infile); 40337426Sbostic } 40437426Sbostic fname[len++] = '\0'; 40537426Sbostic 40637426Sbostic if (newname) 40737426Sbostic free(newname); 40837426Sbostic newname = (char *) ckalloc(len); 40937426Sbostic strcpy(newname, fname); 41037426Sbostic } 41137426Sbostic 41237426Sbostic while (c != '\n') 41337426Sbostic if (c == EOF) 41437426Sbostic return (STEOF); 41537426Sbostic else 41637426Sbostic c = getc(infile); 41737426Sbostic goto top; 41837426Sbostic } 41937426Sbostic 42037426Sbostic else if(c != EOF) 42137426Sbostic { 42237426Sbostic /* a tab in columns 1-6 skips to column 7 */ 42337426Sbostic ungetc(c, infile); 42437426Sbostic for(p=a; p<aend && (c=getc(infile)) != '\n' && c!=EOF; ) 42537426Sbostic if(c == '\t') 42637426Sbostic { 42737426Sbostic while(p < aend) 42837426Sbostic *p++ = BLANK; 42937426Sbostic speclin = YES; 43037426Sbostic bend = send; 43137426Sbostic } 43237426Sbostic else 43337426Sbostic *p++ = c; 43437426Sbostic } 43537426Sbostic if(c == EOF) 43637426Sbostic return(STEOF); 43737426Sbostic if(c == '\n') 43837426Sbostic { 43937426Sbostic while(p < aend) 44037426Sbostic *p++ = BLANK; 44137426Sbostic if( ! speclin ) 44237426Sbostic while(endcd < bend) 44337426Sbostic *endcd++ = BLANK; 44437426Sbostic } 44537426Sbostic else { /* read body of line */ 44637426Sbostic while( endcd<bend && (c=getc(infile)) != '\n' && c!=EOF ) 44737426Sbostic *endcd++ = c; 44837426Sbostic if(c == EOF) 44937426Sbostic return(STEOF); 45037426Sbostic if(c != '\n') 45137426Sbostic { 45237426Sbostic while( (c=getc(infile)) != '\n') 45337426Sbostic if(c == EOF) 45437426Sbostic return(STEOF); 45537426Sbostic } 45637426Sbostic 45737426Sbostic if( ! speclin ) 45837426Sbostic while(endcd < bend) 45937426Sbostic *endcd++ = BLANK; 46037426Sbostic } 46137426Sbostic ++thislin; 46237426Sbostic if( !isspace(a[5]) && a[5]!='0') 46337426Sbostic return(STCONTINUE); 46437426Sbostic for(p=a; p<aend; ++p) 46537426Sbostic if( !isspace(*p) ) goto initline; 46637426Sbostic for(p = b ; p<endcd ; ++p) 46737426Sbostic if( !isspace(*p) ) goto initline; 46837426Sbostic goto top; 46937426Sbostic 47037426Sbostic initline: 47137426Sbostic nxtstno = 0; 47237426Sbostic for(p = a ; p<a+5 ; ++p) 47337426Sbostic if( !isspace(*p) ) 47437426Sbostic if(isdigit(*p)) 47537426Sbostic nxtstno = 10*nxtstno + (*p - '0'); 47637426Sbostic else { 47737426Sbostic if (newname) 47837426Sbostic { 47937426Sbostic free(infname); 48037426Sbostic infname = newname; 48137426Sbostic newname = NULL; 48237426Sbostic } 48337426Sbostic lineno = thislin; 48437426Sbostic err("nondigit in statement number field"); 48537426Sbostic nxtstno = 0; 48637426Sbostic break; 48737426Sbostic } 48837426Sbostic return(STINITIAL); 48937426Sbostic } 49037426Sbostic 49137426Sbostic LOCAL crunch() 49237426Sbostic { 49337426Sbostic register char *i, *j, *j0, *j1, *prvstr; 49437426Sbostic int ten, nh, quote; 49537426Sbostic 49637426Sbostic /* i is the next input character to be looked at 49737426Sbostic j is the next output character */ 49837426Sbostic parlev = 0; 49937426Sbostic expcom = 0; /* exposed ','s */ 50037426Sbostic expeql = 0; /* exposed equal signs */ 50137426Sbostic j = s; 50237426Sbostic prvstr = s; 50337426Sbostic for(i=s ; i<=lastch ; ++i) 50437426Sbostic { 50537426Sbostic if(isspace(*i) ) 50637426Sbostic continue; 50737426Sbostic if(*i=='\'' || *i=='"') 50837426Sbostic { 50937426Sbostic quote = *i; 51037426Sbostic *j = MYQUOTE; /* special marker */ 51137426Sbostic for(;;) 51237426Sbostic { 51337426Sbostic if(++i > lastch) 51437426Sbostic { 51537426Sbostic err("unbalanced quotes; closing quote supplied"); 51637426Sbostic break; 51737426Sbostic } 51837426Sbostic if(*i == quote) 51937426Sbostic if(i<lastch && i[1]==quote) ++i; 52037426Sbostic else break; 52137426Sbostic else if(*i=='\\' && i<lastch) 52237426Sbostic switch(*++i) 52337426Sbostic { 52437426Sbostic case 't': 52537426Sbostic *i = '\t'; break; 52637426Sbostic case 'b': 52737426Sbostic *i = '\b'; break; 52837426Sbostic case 'n': 52937426Sbostic *i = '\n'; break; 53037426Sbostic case 'f': 53137426Sbostic *i = '\f'; break; 53237426Sbostic case 'v': 53337426Sbostic *i = '\v'; break; 53437426Sbostic case '0': 53537426Sbostic *i = '\0'; break; 53637426Sbostic default: 53737426Sbostic break; 53837426Sbostic } 53937426Sbostic *++j = *i; 54037426Sbostic } 54137426Sbostic j[1] = MYQUOTE; 54237426Sbostic j += 2; 54337426Sbostic prvstr = j; 54437426Sbostic } 54537426Sbostic else if( (*i=='h' || *i=='H') && j>prvstr) /* test for Hollerith strings */ 54637426Sbostic { 54737426Sbostic if( ! isdigit(j[-1])) goto copychar; 54837426Sbostic nh = j[-1] - '0'; 54937426Sbostic ten = 10; 55037426Sbostic j1 = prvstr - 1; 55137426Sbostic if (j1<j-5) j1=j-5; 55237426Sbostic for(j0=j-2 ; j0>j1; -- j0) 55337426Sbostic { 55437426Sbostic if( ! isdigit(*j0 ) ) break; 55537426Sbostic nh += ten * (*j0-'0'); 55637426Sbostic ten*=10; 55737426Sbostic } 55837426Sbostic if(j0 <= j1) goto copychar; 55937426Sbostic /* a hollerith must be preceded by a punctuation mark. 56037426Sbostic '*' is possible only as repetition factor in a data statement 56137426Sbostic not, in particular, in character*2h 56237426Sbostic */ 56337426Sbostic 56437426Sbostic if( !(*j0=='*'&&s[0]=='d') && *j0!='/' && *j0!='(' && 56537426Sbostic *j0!=',' && *j0!='=' && *j0!='.') 56637426Sbostic goto copychar; 56737426Sbostic if(i+nh > lastch) 56837426Sbostic { 56937426Sbostic erri("%dH too big", nh); 57037426Sbostic nh = lastch - i; 57137426Sbostic } 57237426Sbostic j0[1] = MYQUOTE; /* special marker */ 57337426Sbostic j = j0 + 1; 57437426Sbostic while(nh-- > 0) 57537426Sbostic { 57637426Sbostic if(*++i == '\\') 57737426Sbostic switch(*++i) 57837426Sbostic { 57937426Sbostic case 't': 58037426Sbostic *i = '\t'; break; 58137426Sbostic case 'b': 58237426Sbostic *i = '\b'; break; 58337426Sbostic case 'n': 58437426Sbostic *i = '\n'; break; 58537426Sbostic case 'f': 58637426Sbostic *i = '\f'; break; 58737426Sbostic case '0': 58837426Sbostic *i = '\0'; break; 58937426Sbostic default: 59037426Sbostic break; 59137426Sbostic } 59237426Sbostic *++j = *i; 59337426Sbostic } 59437426Sbostic j[1] = MYQUOTE; 59537426Sbostic j+=2; 59637426Sbostic prvstr = j; 59737426Sbostic } 59837426Sbostic else { 59937426Sbostic if(*i == '(') ++parlev; 60037426Sbostic else if(*i == ')') --parlev; 60137426Sbostic else if(parlev == 0) 60237426Sbostic if(*i == '=') expeql = 1; 60337426Sbostic else if(*i == ',') expcom = 1; 60437426Sbostic copychar: /*not a string or space -- copy, shifting case if necessary */ 60537426Sbostic if(shiftcase && isupper(*i)) 60637426Sbostic *j++ = tolower(*i); 60737426Sbostic else *j++ = *i; 60837426Sbostic } 60937426Sbostic } 61037426Sbostic lastch = j - 1; 61137426Sbostic nextch = s; 61237426Sbostic } 61337426Sbostic 61437426Sbostic LOCAL analyz() 61537426Sbostic { 61637426Sbostic register char *i; 61737426Sbostic 61837426Sbostic if(parlev != 0) 61937426Sbostic { 62037426Sbostic err("unbalanced parentheses, statement skipped"); 62137426Sbostic stkey = SUNKNOWN; 62237426Sbostic return; 62337426Sbostic } 62437426Sbostic if(nextch+2<=lastch && nextch[0]=='i' && nextch[1]=='f' && nextch[2]=='(') 62537426Sbostic { 62637426Sbostic /* assignment or if statement -- look at character after balancing paren */ 62737426Sbostic parlev = 1; 62837426Sbostic for(i=nextch+3 ; i<=lastch; ++i) 62937426Sbostic if(*i == (MYQUOTE)) 63037426Sbostic { 63137426Sbostic while(*++i != MYQUOTE) 63237426Sbostic ; 63337426Sbostic } 63437426Sbostic else if(*i == '(') 63537426Sbostic ++parlev; 63637426Sbostic else if(*i == ')') 63737426Sbostic { 63837426Sbostic if(--parlev == 0) 63937426Sbostic break; 64037426Sbostic } 64137426Sbostic if(i >= lastch) 64237426Sbostic stkey = SLOGIF; 64337426Sbostic else if(i[1] == '=') 64437426Sbostic stkey = SLET; 64537426Sbostic else if( isdigit(i[1]) ) 64637426Sbostic stkey = SARITHIF; 64737426Sbostic else stkey = SLOGIF; 64837426Sbostic if(stkey != SLET) 64937426Sbostic nextch += 2; 65037426Sbostic } 65137426Sbostic else if(expeql) /* may be an assignment */ 65237426Sbostic { 65337426Sbostic if(expcom && nextch<lastch && 65437426Sbostic nextch[0]=='d' && nextch[1]=='o') 65537426Sbostic { 65637426Sbostic stkey = SDO; 65737426Sbostic nextch += 2; 65837426Sbostic } 65937426Sbostic else stkey = SLET; 66037426Sbostic } 66137426Sbostic /* otherwise search for keyword */ 66237426Sbostic else { 66337426Sbostic stkey = getkwd(); 66437426Sbostic if(stkey==SGOTO && lastch>=nextch) 66537426Sbostic if(nextch[0]=='(') 66637426Sbostic stkey = SCOMPGOTO; 66737426Sbostic else if(isalpha(nextch[0])) 66837426Sbostic stkey = SASGOTO; 66937426Sbostic } 67037426Sbostic parlev = 0; 67137426Sbostic } 67237426Sbostic 67337426Sbostic 67437426Sbostic 67537426Sbostic LOCAL getkwd() 67637426Sbostic { 67737426Sbostic register char *i, *j; 67837426Sbostic register struct Keylist *pk, *pend; 67937426Sbostic int k; 68037426Sbostic 68137426Sbostic if(! isalpha(nextch[0]) ) 68237426Sbostic return(SUNKNOWN); 68337426Sbostic k = nextch[0] - 'a'; 68437426Sbostic if(pk = keystart[k]) 68537426Sbostic for(pend = keyend[k] ; pk<=pend ; ++pk ) 68637426Sbostic { 68737426Sbostic i = pk->keyname; 68837426Sbostic j = nextch; 68937426Sbostic while(*++i==*++j && *i!='\0') 69037426Sbostic ; 69137426Sbostic if(*i=='\0' && j<=lastch+1) 69237426Sbostic { 69337426Sbostic nextch = j; 69437426Sbostic if(no66flag && pk->notinf66) 69537426Sbostic errstr("Not a Fortran 66 keyword: %s", 69637426Sbostic pk->keyname); 69737426Sbostic return(pk->keyval); 69837426Sbostic } 69937426Sbostic } 70037426Sbostic return(SUNKNOWN); 70137426Sbostic } 70237426Sbostic 70337426Sbostic 70437426Sbostic 70537426Sbostic initkey() 70637426Sbostic { 70737426Sbostic extern struct Keylist keys[]; 70837426Sbostic register struct Keylist *p; 70937426Sbostic register int i,j; 71037426Sbostic 71137426Sbostic for(i = 0 ; i<26 ; ++i) 71237426Sbostic keystart[i] = NULL; 71337426Sbostic 71437426Sbostic for(p = keys ; p->keyname ; ++p) 71537426Sbostic { 71637426Sbostic j = p->keyname[0] - 'a'; 71737426Sbostic if(keystart[j] == NULL) 71837426Sbostic keystart[j] = p; 71937426Sbostic keyend[j] = p; 72037426Sbostic } 72137426Sbostic } 72237426Sbostic 72337426Sbostic LOCAL gettok() 72437426Sbostic { 72537426Sbostic int havdot, havexp, havdbl; 72637426Sbostic int radix, val; 72737426Sbostic extern struct Punctlist puncts[]; 72837426Sbostic struct Punctlist *pp; 72937426Sbostic extern struct Fmtlist fmts[]; 73037426Sbostic extern struct Dotlist dots[]; 73137426Sbostic struct Dotlist *pd; 73237426Sbostic 73337426Sbostic char *i, *j, *n1, *p; 73437426Sbostic 73537426Sbostic if(*nextch == (MYQUOTE)) 73637426Sbostic { 73737426Sbostic ++nextch; 73837426Sbostic p = token; 73937426Sbostic while(*nextch != MYQUOTE) 74037426Sbostic *p++ = *nextch++; 74137426Sbostic ++nextch; 74237426Sbostic toklen = p - token; 74337426Sbostic *p = '\0'; 74437426Sbostic return (SHOLLERITH); 74537426Sbostic } 74637426Sbostic /* 74737426Sbostic if(stkey == SFORMAT) 74837426Sbostic { 74937426Sbostic for(pf = fmts; pf->fmtchar; ++pf) 75037426Sbostic { 75137426Sbostic if(*nextch == pf->fmtchar) 75237426Sbostic { 75337426Sbostic ++nextch; 75437426Sbostic if(pf->fmtval == SLPAR) 75537426Sbostic ++parlev; 75637426Sbostic else if(pf->fmtval == SRPAR) 75737426Sbostic --parlev; 75837426Sbostic return(pf->fmtval); 75937426Sbostic } 76037426Sbostic } 76137426Sbostic if( isdigit(*nextch) ) 76237426Sbostic { 76337426Sbostic p = token; 76437426Sbostic *p++ = *nextch++; 76537426Sbostic while(nextch<=lastch && isdigit(*nextch) ) 76637426Sbostic *p++ = *nextch++; 76737426Sbostic toklen = p - token; 76837426Sbostic *p = '\0'; 76937426Sbostic if(nextch<=lastch && *nextch=='p') 77037426Sbostic { 77137426Sbostic ++nextch; 77237426Sbostic return(SSCALE); 77337426Sbostic } 77437426Sbostic else return(SICON); 77537426Sbostic } 77637426Sbostic if( isalpha(*nextch) ) 77737426Sbostic { 77837426Sbostic p = token; 77937426Sbostic *p++ = *nextch++; 78037426Sbostic while(nextch<=lastch && 78137426Sbostic (*nextch=='.' || isdigit(*nextch) || isalpha(*nextch) )) 78237426Sbostic *p++ = *nextch++; 78337426Sbostic toklen = p - token; 78437426Sbostic *p = '\0'; 78537426Sbostic return(SFIELD); 78637426Sbostic } 78737426Sbostic goto badchar; 78837426Sbostic } 78937426Sbostic /* Not a format statement */ 79037426Sbostic 79137426Sbostic if(needkwd) 79237426Sbostic { 79337426Sbostic needkwd = 0; 79437426Sbostic return( getkwd() ); 79537426Sbostic } 79637426Sbostic 79737426Sbostic for(pp=puncts; pp->punchar; ++pp) 79837426Sbostic if(*nextch == pp->punchar) 79937426Sbostic { 80037426Sbostic if( (*nextch=='*' || *nextch=='/') && 80137426Sbostic nextch<lastch && nextch[1]==nextch[0]) 80237426Sbostic { 80337426Sbostic if(*nextch == '*') 80437426Sbostic val = SPOWER; 80537426Sbostic else val = SCONCAT; 80637426Sbostic nextch+=2; 80737426Sbostic } 80837426Sbostic else { 80937426Sbostic val = pp->punval; 81037426Sbostic if(val==SLPAR) 81137426Sbostic ++parlev; 81237426Sbostic else if(val==SRPAR) 81337426Sbostic --parlev; 81437426Sbostic ++nextch; 81537426Sbostic } 81637426Sbostic return(val); 81737426Sbostic } 81837426Sbostic if(*nextch == '.') 81937426Sbostic if(nextch >= lastch) goto badchar; 82037426Sbostic else if(isdigit(nextch[1])) goto numconst; 82137426Sbostic else { 82237426Sbostic for(pd=dots ; (j=pd->dotname) ; ++pd) 82337426Sbostic { 82437426Sbostic for(i=nextch+1 ; i<=lastch ; ++i) 82537426Sbostic if(*i != *j) break; 82637426Sbostic else if(*i != '.') ++j; 82737426Sbostic else { 82837426Sbostic nextch = i+1; 82937426Sbostic return(pd->dotval); 83037426Sbostic } 83137426Sbostic } 83237426Sbostic goto badchar; 83337426Sbostic } 83437426Sbostic if( isalpha(*nextch) ) 83537426Sbostic { 83637426Sbostic p = token; 83737426Sbostic *p++ = *nextch++; 83837426Sbostic while(nextch<=lastch) 83937426Sbostic if( isalpha(*nextch) || isdigit(*nextch) ) 84037426Sbostic *p++ = *nextch++; 84137426Sbostic else break; 84237426Sbostic toklen = p - token; 84337426Sbostic *p = '\0'; 84437426Sbostic if(inioctl && nextch<=lastch && *nextch=='=') 84537426Sbostic { 84637426Sbostic ++nextch; 84737426Sbostic return(SNAMEEQ); 84837426Sbostic } 84937426Sbostic if(toklen>8 && eqn(8,token,"function") && isalpha(token[8]) && 85037426Sbostic nextch<lastch && nextch[0]=='(' && 85137426Sbostic (nextch[1]==')' | isalpha(nextch[1])) ) 85237426Sbostic { 85337426Sbostic nextch -= (toklen - 8); 85437426Sbostic return(SFUNCTION); 85537426Sbostic } 85637426Sbostic if(toklen > VL) 85737426Sbostic { 85837426Sbostic char buff[30]; 85937426Sbostic sprintf(buff, "name %s too long, truncated to %d", 86037426Sbostic token, VL); 86137426Sbostic err(buff); 86237426Sbostic toklen = VL; 86337426Sbostic token[VL] = '\0'; 86437426Sbostic } 86537426Sbostic if(toklen==1 && *nextch==MYQUOTE) 86637426Sbostic { 86737426Sbostic switch(token[0]) 86837426Sbostic { 86937426Sbostic case 'z': case 'Z': 87037426Sbostic case 'x': case 'X': 87137426Sbostic radix = 16; break; 87237426Sbostic case 'o': case 'O': 87337426Sbostic radix = 8; break; 87437426Sbostic case 'b': case 'B': 87537426Sbostic radix = 2; break; 87637426Sbostic default: 87737426Sbostic err("bad bit identifier"); 87837426Sbostic return(SNAME); 87937426Sbostic } 88037426Sbostic ++nextch; 88137426Sbostic for(p = token ; *nextch!=MYQUOTE ; ) 88237426Sbostic if ( *nextch == BLANK || *nextch == '\t') 88337426Sbostic nextch++; 88437426Sbostic else 88537426Sbostic { 88637426Sbostic if (isupper(*nextch)) 88737426Sbostic *nextch = tolower(*nextch); 88837426Sbostic if (hextoi(*p++ = *nextch++) >= radix) 88937426Sbostic { 89037426Sbostic err("invalid binary character"); 89137426Sbostic break; 89237426Sbostic } 89337426Sbostic } 89437426Sbostic ++nextch; 89537426Sbostic toklen = p - token; 89637426Sbostic return( radix==16 ? SHEXCON : 89737426Sbostic (radix==8 ? SOCTCON : SBITCON) ); 89837426Sbostic } 89937426Sbostic return(SNAME); 90037426Sbostic } 90137426Sbostic if( ! isdigit(*nextch) ) goto badchar; 90237426Sbostic numconst: 90337426Sbostic havdot = NO; 90437426Sbostic havexp = NO; 90537426Sbostic havdbl = NO; 90637426Sbostic for(n1 = nextch ; nextch<=lastch ; ++nextch) 90737426Sbostic { 90837426Sbostic if(*nextch == '.') 90937426Sbostic if(havdot) break; 91037426Sbostic else if(nextch+2<=lastch && isalpha(nextch[1]) 91137426Sbostic && isalpha(nextch[2])) 91237426Sbostic break; 91337426Sbostic else havdot = YES; 91437426Sbostic else if( !intonly && (*nextch=='d' || *nextch=='e') ) 91537426Sbostic { 91637426Sbostic p = nextch; 91737426Sbostic havexp = YES; 91837426Sbostic if(*nextch == 'd') 91937426Sbostic havdbl = YES; 92037426Sbostic if(nextch<lastch) 92137426Sbostic if(nextch[1]=='+' || nextch[1]=='-') 92237426Sbostic ++nextch; 92337426Sbostic if( (nextch >= lastch) || ! isdigit(*++nextch) ) 92437426Sbostic { 92537426Sbostic nextch = p; 92637426Sbostic havdbl = havexp = NO; 92737426Sbostic break; 92837426Sbostic } 92937426Sbostic for(++nextch ; 93037426Sbostic nextch<=lastch && isdigit(*nextch); 93137426Sbostic ++nextch); 93237426Sbostic break; 93337426Sbostic } 93437426Sbostic else if( ! isdigit(*nextch) ) 93537426Sbostic break; 93637426Sbostic } 93737426Sbostic p = token; 93837426Sbostic i = n1; 93937426Sbostic while(i < nextch) 94037426Sbostic *p++ = *i++; 94137426Sbostic toklen = p - token; 94237426Sbostic *p = '\0'; 94337426Sbostic if(havdbl) return(SDCON); 94437426Sbostic if(havdot || havexp) return(SRCON); 94537426Sbostic return(SICON); 94637426Sbostic badchar: 94737426Sbostic s[0] = *nextch++; 94837426Sbostic return(SUNKNOWN); 94937426Sbostic } 95037426Sbostic 95137426Sbostic /* KEYWORD AND SPECIAL CHARACTER TABLES 95237426Sbostic */ 95337426Sbostic 95437426Sbostic struct Punctlist puncts[ ] = 95537426Sbostic { 95637426Sbostic '(', SLPAR, 95737426Sbostic ')', SRPAR, 95837426Sbostic '=', SEQUALS, 95937426Sbostic ',', SCOMMA, 96037426Sbostic '+', SPLUS, 96137426Sbostic '-', SMINUS, 96237426Sbostic '*', SSTAR, 96337426Sbostic '/', SSLASH, 96437426Sbostic '$', SCURRENCY, 96537426Sbostic ':', SCOLON, 96637426Sbostic 0, 0 } ; 96737426Sbostic 96837426Sbostic /* 96937426Sbostic LOCAL struct Fmtlist fmts[ ] = 97037426Sbostic { 97137426Sbostic '(', SLPAR, 97237426Sbostic ')', SRPAR, 97337426Sbostic '/', SSLASH, 97437426Sbostic ',', SCOMMA, 97537426Sbostic '-', SMINUS, 97637426Sbostic ':', SCOLON, 97737426Sbostic 0, 0 } ; 97837426Sbostic */ 97937426Sbostic 98037426Sbostic LOCAL struct Dotlist dots[ ] = 98137426Sbostic { 98237426Sbostic "and.", SAND, 98337426Sbostic "or.", SOR, 98437426Sbostic "not.", SNOT, 98537426Sbostic "true.", STRUE, 98637426Sbostic "false.", SFALSE, 98737426Sbostic "eq.", SEQ, 98837426Sbostic "ne.", SNE, 98937426Sbostic "lt.", SLT, 99037426Sbostic "le.", SLE, 99137426Sbostic "gt.", SGT, 99237426Sbostic "ge.", SGE, 99337426Sbostic "neqv.", SNEQV, 99437426Sbostic "eqv.", SEQV, 99537426Sbostic 0, 0 } ; 99637426Sbostic 99737426Sbostic LOCAL struct Keylist keys[ ] = 99837426Sbostic { 99937426Sbostic { "assign", SASSIGN }, 100037426Sbostic { "automatic", SAUTOMATIC, YES }, 100137426Sbostic { "backspace", SBACKSPACE }, 100237426Sbostic { "blockdata", SBLOCK }, 100337426Sbostic { "call", SCALL }, 100437426Sbostic { "character", SCHARACTER, YES }, 100537426Sbostic { "close", SCLOSE, YES }, 100637426Sbostic { "common", SCOMMON }, 100737426Sbostic { "complex", SCOMPLEX }, 100837426Sbostic { "continue", SCONTINUE }, 100937426Sbostic { "data", SDATA }, 101037426Sbostic { "dimension", SDIMENSION }, 101137426Sbostic { "doubleprecision", SDOUBLE }, 101237426Sbostic { "doublecomplex", SDCOMPLEX, YES }, 101337426Sbostic { "elseif", SELSEIF, YES }, 101437426Sbostic { "else", SELSE, YES }, 101537426Sbostic { "endfile", SENDFILE }, 101637426Sbostic { "endif", SENDIF, YES }, 101737426Sbostic { "end", SEND }, 101837426Sbostic { "entry", SENTRY, YES }, 101937426Sbostic { "equivalence", SEQUIV }, 102037426Sbostic { "external", SEXTERNAL }, 102137426Sbostic { "format", SFORMAT }, 102237426Sbostic { "function", SFUNCTION }, 102337426Sbostic { "goto", SGOTO }, 102437426Sbostic { "implicit", SIMPLICIT, YES }, 102537426Sbostic { "include", SINCLUDE, YES }, 102637426Sbostic { "inquire", SINQUIRE, YES }, 102737426Sbostic { "intrinsic", SINTRINSIC, YES }, 102837426Sbostic { "integer", SINTEGER }, 102937426Sbostic { "logical", SLOGICAL }, 103037426Sbostic #ifdef NAMELIST 103137426Sbostic { "namelist", SNAMELIST, YES }, 103237426Sbostic #endif 103337426Sbostic { "none", SUNDEFINED, YES }, 103437426Sbostic { "open", SOPEN, YES }, 103537426Sbostic { "parameter", SPARAM, YES }, 103637426Sbostic { "pause", SPAUSE }, 103737426Sbostic { "print", SPRINT }, 103837426Sbostic { "program", SPROGRAM, YES }, 103937426Sbostic { "punch", SPUNCH, YES }, 104037426Sbostic { "read", SREAD }, 104137426Sbostic { "real", SREAL }, 104237426Sbostic { "return", SRETURN }, 104337426Sbostic { "rewind", SREWIND }, 104437426Sbostic { "save", SSAVE, YES }, 104537426Sbostic { "static", SSTATIC, YES }, 104637426Sbostic { "stop", SSTOP }, 104737426Sbostic { "subroutine", SSUBROUTINE }, 104837426Sbostic { "then", STHEN, YES }, 104937426Sbostic { "undefined", SUNDEFINED, YES }, 105037426Sbostic { "write", SWRITE }, 105137426Sbostic { 0, 0 } 105237426Sbostic }; 1053