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