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