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