|
|
1.1 root 1: #ifndef lint
2: static char *sccsid ="@(#)scan.c 2.1 (Berkeley) 4/23/86";
3: #endif lint
4:
5: # include "pass1.h"
6: # include <a.out.h>
7: # include <stab.h>
8: # include <ctype.h>
9: # include <signal.h>
10:
11: /* temporarily */
12:
13: int asm_esc = 0; /* asm escaped used in file */
14: /* lexical actions */
15:
16: # define A_ERR 0 /* illegal character */
17: # define A_LET 1 /* saw a letter */
18: # define A_DIG 2 /* saw a digit */
19: # define A_1C 3 /* return a single character */
20: # define A_STR 4 /* string */
21: # define A_CC 5 /* character constant */
22: # define A_BCD 6 /* GCOS BCD constant */
23: # define A_SL 7 /* saw a / */
24: # define A_DOT 8 /* saw a . */
25: # define A_PL 9 /* + */
26: # define A_MI 10 /* - */
27: # define A_EQ 11 /* = */
28: # define A_NOT 12 /* ! */
29: # define A_LT 13 /* < */
30: # define A_GT 14 /* > */
31: # define A_AND 16 /* & */
32: # define A_OR 17 /* | */
33: # define A_WS 18 /* whitespace (not \n) */
34: # define A_NL 19 /* \n */
35:
36: /* character classes */
37:
38: # define LEXLET 01
39: # define LEXDIG 02
40: # define LEXOCT 04
41: # define LEXHEX 010
42: # define LEXWS 020
43: # define LEXDOT 040
44:
45: /* reserved word actions */
46:
47: # define AR_TY 0 /* type word */
48: # define AR_RW 1 /* simple reserved word */
49: # define AR_CL 2 /* storage class word */
50: # define AR_S 3 /* struct */
51: # define AR_U 4 /* union */
52: # define AR_E 5 /* enum */
53: # define AR_A 6 /* asm */
54:
55: /* text buffer */
56: #ifndef FLEXNAMES
57: # define LXTSZ 100
58: #else
59: #define LXTSZ BUFSIZ
60: #endif
61: char yytext[LXTSZ];
62: char * lxgcp;
63:
64: extern int proflg;
65: extern int gdebug;
66: extern int fpe();
67: struct sigvec fpe_sigvec;
68: int oldway; /* allocate storage so lint will compile as well */
69: #ifndef LINT
70: extern int lastloc;
71: #endif
72:
73: unsigned caloff();
74: /* ARGSUSED */
75: mainp1( argc, argv ) int argc; char *argv[]; { /* control multiple files */
76:
77: register i;
78: register char *cp;
79: extern int idebug, bdebug, tdebug, edebug;
80: extern int ddebug, xdebug, gdebug, adebug;
81: extern unsigned int offsz;
82: int fdef = 0;
83: char *release = "PCC/2.1 (Berkeley) 4/23/86";
84:
85: offsz = caloff();
86: for( i=1; i<argc; ++i ){
87: if( *(cp=argv[i]) == '-' && *++cp == 'X' ){
88: while( *++cp ){
89: switch( *cp ){
90:
91: case 'r':
92: fprintf( stderr, "Release: %s\n",
93: release );
94: break;
95:
96: case 'd':
97: ++ddebug;
98: break;
99: case 'i':
100: ++idebug;
101: break;
102: case 'b':
103: ++bdebug;
104: break;
105: case 't':
106: ++tdebug;
107: break;
108: case 'e':
109: ++edebug;
110: break;
111: case 'x':
112: ++xdebug;
113: break;
114: case 'P': /* profiling */
115: ++proflg;
116: break;
117: case 'g':
118: ++gdebug;
119: break;
120: case 'a':
121: ++adebug;
122: break;
123: case 'G':
124: ++gdebug;
125: oldway = 1;
126: break;
127: }
128: }
129: }
130: else {
131: if( *(argv[i]) != '-' ) switch( fdef++ ) {
132: case 0:
133: case 1:
134: if( freopen(argv[i], fdef==1 ? "r" : "w", fdef==1 ? stdin : stdout) == NULL) {
135: fprintf(stderr, "ccom:can't open %s\n", argv[i]);
136: exit(1);
137: }
138: break;
139:
140: default:
141: ;
142: }
143: }
144: }
145:
146: # ifdef ONEPASS
147: p2init( argc, argv );
148: # endif
149:
150: for( i=0; i<SYMTSZ; ++i ) stab[i].stype = TNULL;
151:
152: lineno = 1;
153:
154: lxinit();
155: tinit();
156: mkdope();
157:
158: /* dimension table initialization */
159:
160: dimtab[NULL] = 0;
161: dimtab[CHAR] = SZCHAR;
162: dimtab[INT] = SZINT;
163: dimtab[FLOAT] = SZFLOAT;
164: dimtab[DOUBLE] = SZDOUBLE;
165: dimtab[LONG] = SZLONG;
166: dimtab[SHORT] = SZSHORT;
167: dimtab[UCHAR] = SZCHAR;
168: dimtab[USHORT] = SZSHORT;
169: dimtab[UNSIGNED] = SZINT;
170: dimtab[ULONG] = SZLONG;
171: /* starts past any of the above */
172: curdim = 16;
173: reached = 1;
174:
175: fpe_sigvec.sv_handler = fpe;
176: (void) sigvec(SIGFPE, &fpe_sigvec, (struct sigvec *) NULL);
177:
178: yyparse();
179: yyaccpt();
180:
181: ejobcode( nerrors ? 1 : 0 );
182: return(nerrors?1:0);
183:
184: }
185:
186: # ifdef ibm
187:
188: # define CSMASK 0377
189: # define CSSZ 256
190:
191: # else
192:
193: # define CSMASK 0177
194: # define CSSZ 128
195:
196: # endif
197:
198: short lxmask[CSSZ+1];
199:
200: lxenter( s, m ) register char *s; register short m; {
201: /* enter a mask into lxmask */
202: register c;
203:
204: while( c= *s++ ) lxmask[c+1] |= m;
205:
206: }
207:
208:
209: # define lxget(c,m) (lxgcp=yytext,lxmore(c,m))
210:
211: lxmore( c, m ) register c, m; {
212: register char *cp;
213:
214: *(cp = lxgcp) = c;
215: while( c=getchar(), lxmask[c+1]&m ){
216: if( cp < &yytext[LXTSZ-1] ){
217: *++cp = c;
218: }
219: }
220: ungetc(c,stdin);
221: *(lxgcp = cp+1) = '\0';
222: }
223:
224: struct lxdope {
225: short lxch; /* the character */
226: short lxact; /* the action to be performed */
227: short lxtok; /* the token number to be returned */
228: short lxval; /* the value to be returned */
229: } lxdope[] = {
230:
231: '@', A_ERR, 0, 0, /* illegal characters go here... */
232: '_', A_LET, 0, 0, /* letters point here */
233: '0', A_DIG, 0, 0, /* digits point here */
234: ' ', A_WS, 0, 0, /* whitespace goes here */
235: '\n', A_NL, 0, 0,
236: '"', A_STR, 0, 0, /* character string */
237: '\'', A_CC, 0, 0, /* character constant */
238: '`', A_BCD, 0, 0, /* GCOS BCD constant */
239: '(', A_1C, LP, 0,
240: ')', A_1C, RP, 0,
241: '{', A_1C, LC, 0,
242: '}', A_1C, RC, 0,
243: '[', A_1C, LB, 0,
244: ']', A_1C, RB, 0,
245: '*', A_1C, MUL, MUL,
246: '?', A_1C, QUEST, 0,
247: ':', A_1C, COLON, 0,
248: '+', A_PL, PLUS, PLUS,
249: '-', A_MI, MINUS, MINUS,
250: '/', A_SL, DIVOP, DIV,
251: '%', A_1C, DIVOP, MOD,
252: '&', A_AND, AND, AND,
253: '|', A_OR, OR, OR,
254: '^', A_1C, ER, ER,
255: '!', A_NOT, UNOP, NOT,
256: '~', A_1C, UNOP, COMPL,
257: ',', A_1C, CM, CM,
258: ';', A_1C, SM, 0,
259: '.', A_DOT, STROP, DOT,
260: '<', A_LT, RELOP, LT,
261: '>', A_GT, RELOP, GT,
262: '=', A_EQ, ASSIGN, ASSIGN,
263: -1, A_1C, 0, 0,
264: };
265:
266: struct lxdope *lxcp[CSSZ+1];
267:
268: lxinit(){
269: register struct lxdope *p;
270: register i;
271: register char *cp;
272: /* set up character classes */
273:
274: lxenter( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$", LEXLET );
275: lxenter( "0123456789", LEXDIG );
276: lxenter( "0123456789abcdefABCDEF", LEXHEX );
277: /* \013 should become \v someday; \013 is OK for ASCII and EBCDIC */
278: lxenter( " \t\r\b\f\013", LEXWS );
279: lxenter( "01234567", LEXOCT );
280: lxmask['.'+1] |= LEXDOT;
281:
282: /* make lxcp point to appropriate lxdope entry for each character */
283:
284: /* initialize error entries */
285:
286: for( i= 0; i<=CSSZ; ++i ) lxcp[i] = lxdope;
287:
288: /* make unique entries */
289:
290: for( p=lxdope; ; ++p ) {
291: lxcp[p->lxch+1] = p;
292: if( p->lxch < 0 ) break;
293: }
294:
295: /* handle letters, digits, and whitespace */
296: /* by convention, first, second, and third places */
297:
298: cp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$";
299: while( *cp ) lxcp[*cp++ + 1] = &lxdope[1];
300: cp = "123456789";
301: while( *cp ) lxcp[*cp++ + 1] = &lxdope[2];
302: cp = "\t\b\r\f\013";
303: while( *cp ) lxcp[*cp++ + 1] = &lxdope[3];
304:
305: /* first line might have title */
306: lxtitle();
307:
308: }
309:
310: int lxmatch; /* character to be matched in char or string constant */
311:
312: lxstr(ct){
313: /* match a string or character constant, up to lxmatch */
314:
315: register c;
316: register val;
317: register i;
318:
319: i=0;
320: while( (c=getchar()) != lxmatch ){
321: switch( c ) {
322:
323: case EOF:
324: uerror( "unexpected EOF" );
325: break;
326:
327: case '\n':
328: uerror( "newline in string or char constant" );
329: ++lineno;
330: break;
331:
332: case '\\':
333: switch( c = getchar() ){
334:
335: case '\n':
336: ++lineno;
337: continue;
338:
339: default:
340: val = c;
341: goto mkcc;
342:
343: case 'n':
344: val = '\n';
345: goto mkcc;
346:
347: case 'r':
348: val = '\r';
349: goto mkcc;
350:
351: case 'b':
352: val = '\b';
353: goto mkcc;
354:
355: case 't':
356: val = '\t';
357: goto mkcc;
358:
359: case 'f':
360: val = '\f';
361: goto mkcc;
362:
363: case 'v':
364: val = '\013';
365: goto mkcc;
366:
367: case '0':
368: case '1':
369: case '2':
370: case '3':
371: case '4':
372: case '5':
373: case '6':
374: case '7':
375: val = c-'0';
376: c=getchar(); /* try for 2 */
377: if( lxmask[c+1] & LEXOCT ){
378: val = (val<<3) | (c-'0');
379: c = getchar(); /* try for 3 */
380: if( lxmask[c+1] & LEXOCT ){
381: val = (val<<3) | (c-'0');
382: }
383: else ungetc( c ,stdin);
384: }
385: else ungetc( c ,stdin);
386:
387: goto mkcc1;
388:
389: }
390: default:
391: val =c;
392: mkcc:
393: val = CCTRANS(val);
394: mkcc1:
395: if( lxmatch == '\'' ){
396: val = CHARCAST(val); /* it is, after all, a "character" constant */
397: makecc( val, i );
398: }
399: else { /* stash the byte into the string */
400: if( strflg ) {
401: if( ct==0 || i<ct ) putbyte( val );
402: else if( i == ct ) werror( "non-null byte ignored in string initializer" );
403: }
404: else bycode( val, i );
405: }
406: ++i;
407: continue;
408: }
409: break;
410: }
411: /* end of string or char constant */
412:
413: if( lxmatch == '"' ){
414: if( strflg ){ /* end the string */
415: if( ct==0 || i<ct ) putbyte( 0 ); /* the null at the end */
416: }
417: else { /* the initializer gets a null byte */
418: bycode( 0, i++ );
419: bycode( -1, i );
420: dimtab[curdim] = i; /* in case of later sizeof ... */
421: }
422: }
423: else { /* end the character constant */
424: if( i == 0 ) uerror( "empty character constant" );
425: if( i>(SZINT/SZCHAR) || ( (pflag||hflag)&&i>1) )
426: uerror( "too many characters in character constant" );
427: }
428: }
429:
430: lxcom(){
431: register c;
432: /* saw a /*: process a comment */
433:
434: for(;;){
435:
436: switch( c = getchar() ){
437:
438: case EOF:
439: uerror( "unexpected EOF" );
440: return;
441:
442: case '\n':
443: ++lineno;
444:
445: default:
446: continue;
447:
448: case '*':
449: if( (c = getchar()) == '/' ) return;
450: else ungetc( c ,stdin);
451: continue;
452:
453: # ifdef LINT
454: case 'V':
455: lxget( c, LEXLET|LEXDIG );
456: {
457: extern int vaflag;
458: int i;
459: i = yytext[7]?yytext[7]-'0':0;
460: yytext[7] = '\0';
461: if( strcmp( yytext, "VARARGS" ) ) continue;
462: vaflag = i;
463: continue;
464: }
465: case 'L':
466: lxget( c, LEXLET );
467: if( strcmp( yytext, "LINTLIBRARY" ) ) continue;
468: {
469: extern int libflag;
470: libflag = 1;
471: }
472: continue;
473:
474: case 'A':
475: lxget( c, LEXLET );
476: if( strcmp( yytext, "ARGSUSED" ) ) continue;
477: {
478: extern int argflag, vflag;
479: argflag = 1;
480: vflag = 0;
481: }
482: continue;
483:
484: case 'N':
485: lxget( c, LEXLET );
486: if( strcmp( yytext, "NOTREACHED" ) ) continue;
487: reached = 0;
488: continue;
489: # endif
490: }
491: }
492: }
493:
494: yylex(){
495: for(;;){
496:
497: register lxchar;
498: register struct lxdope *p;
499: register struct symtab *sp;
500: int id;
501:
502: switch( (p=lxcp[(lxchar=getchar())+1])->lxact ){
503:
504: onechar:
505: ungetc( lxchar ,stdin);
506:
507: case A_1C:
508: /* eat up a single character, and return an opcode */
509:
510: yylval.intval = p->lxval;
511: return( p->lxtok );
512:
513: case A_ERR:
514: uerror( "illegal character: %03o (octal)", lxchar );
515: break;
516:
517: case A_LET:
518: /* collect an identifier, check for reserved word, and return */
519: lxget( lxchar, LEXLET|LEXDIG );
520: if( (lxchar=lxres()) > 0 ) return( lxchar ); /* reserved word */
521: if( lxchar== 0 ) continue;
522: #ifdef FLEXNAMES
523: id = lookup( hash(yytext),
524: #else
525: id = lookup( yytext,
526: #endif
527: /* tag name for struct/union/enum */
528: (stwart&TAGNAME)? STAG:
529: /* member name for struct/union */
530: (stwart&(INSTRUCT|INUNION|FUNNYNAME))?SMOS:0 );
531: sp = &stab[id];
532: if( sp->sclass == TYPEDEF && !stwart ){
533: stwart = instruct;
534: yylval.nodep = mkty( sp->stype, sp->dimoff, sp->sizoff );
535: return( TYPE );
536: }
537: stwart = (stwart&SEENAME) ? instruct : 0;
538: yylval.intval = id;
539: return( NAME );
540:
541: case A_DIG:
542: /* collect a digit string, then look at last one... */
543: lastcon = 0;
544: lxget( lxchar, LEXDIG );
545: switch( lxchar=getchar() ){
546:
547: case 'x':
548: case 'X':
549: if( yytext[0] != '0' && !yytext[1] ) uerror( "illegal hex constant" );
550: lxmore( lxchar, LEXHEX );
551: /* convert the value */
552: {
553: register char *cp;
554: for( cp = yytext+2; *cp; ++cp ){
555: /* this code won't work for all wild character sets,
556: but seems ok for ascii and ebcdic */
557: lastcon <<= 4;
558: if( isdigit( *cp ) ) lastcon += *cp-'0';
559: else if( isupper( *cp ) ) lastcon += *cp - 'A'+ 10;
560: else lastcon += *cp - 'a'+ 10;
561: }
562: }
563:
564: hexlong:
565: /* criterion for longness for hex and octal constants is that it
566: fit within 0177777 */
567: if( lastcon & ~0177777L ) yylval.intval = 1;
568: else yylval.intval = 0;
569:
570: goto islong;
571:
572: case '.':
573: lxmore( lxchar, LEXDIG );
574:
575: getfp:
576: if( (lxchar=getchar()) == 'e' || lxchar == 'E' ){ /* exponent */
577:
578: case 'e':
579: case 'E':
580: if( (lxchar=getchar()) == '+' || lxchar == '-' ){
581: *lxgcp++ = 'e';
582: }
583: else {
584: ungetc(lxchar,stdin);
585: lxchar = 'e';
586: }
587: lxmore( lxchar, LEXDIG );
588: /* now have the whole thing... */
589: }
590: else { /* no exponent */
591: ungetc( lxchar ,stdin);
592: }
593: return( isitfloat( yytext ) );
594:
595: default:
596: ungetc( lxchar ,stdin);
597: if( yytext[0] == '0' ){
598: /* convert in octal */
599: register char *cp;
600: for( cp = yytext+1; *cp; ++cp ){
601: lastcon <<= 3;
602: lastcon += *cp - '0';
603: }
604: goto hexlong;
605: }
606: else {
607: /* convert in decimal */
608: register char *cp;
609: for( cp = yytext; *cp; ++cp ){
610: lastcon = lastcon * 10 + *cp - '0';
611: }
612: }
613:
614: /* decide if it is long or not (decimal case) */
615:
616: /* if it is positive and fits in 15 bits, or negative and
617: and fits in 15 bits plus an extended sign, it is int; otherwise long */
618: /* if there is an l or L following, all bets are off... */
619:
620: { CONSZ v;
621: v = lastcon & ~077777L;
622: if( v == 0 || v == ~077777L ) yylval.intval = 0;
623: else yylval.intval = 1;
624: }
625:
626: islong:
627: /* finally, look for trailing L or l */
628: if( (lxchar = getchar()) == 'L' || lxchar == 'l' ) yylval.intval = 1;
629: else ungetc( lxchar ,stdin);
630: return( ICON );
631: }
632:
633: case A_DOT:
634: /* look for a dot: if followed by a digit, floating point */
635: lxchar = getchar();
636: if( lxmask[lxchar+1] & LEXDIG ){
637: ungetc(lxchar,stdin);
638: lxget( '.', LEXDIG );
639: goto getfp;
640: }
641: stwart = FUNNYNAME;
642: goto onechar;
643:
644: case A_STR:
645: /* string constant */
646: lxmatch = '"';
647: return( STRING );
648:
649: case A_CC:
650: /* character constant */
651: lxmatch = '\'';
652: lastcon = 0;
653: lxstr(0);
654: yylval.intval = 0;
655: return( ICON );
656:
657: case A_BCD:
658: {
659: register i;
660: int j;
661: for( i=0; i<LXTSZ; ++i ){
662: if( ( j = getchar() ) == '`' ) break;
663: if( j == '\n' ){
664: uerror( "newline in BCD constant" );
665: break;
666: }
667: yytext[i] = j;
668: }
669: yytext[i] = '\0';
670: if( i>6 ) uerror( "BCD constant exceeds 6 characters" );
671: # ifdef gcos
672: else strtob( yytext, &lastcon, i );
673: lastcon >>= 6*(6-i);
674: # else
675: uerror( "gcos BCD constant illegal" );
676: # endif
677: yylval.intval = 0; /* not long */
678: return( ICON );
679: }
680:
681: case A_SL:
682: /* / */
683: if( (lxchar=getchar()) != '*' ) goto onechar;
684: lxcom();
685: case A_WS:
686: continue;
687:
688: case A_NL:
689: ++lineno;
690: lxtitle();
691: continue;
692:
693: case A_NOT:
694: /* ! */
695: if( (lxchar=getchar()) != '=' ) goto onechar;
696: yylval.intval = NE;
697: return( EQUOP );
698:
699: case A_MI:
700: /* - */
701: if( (lxchar=getchar()) == '-' ){
702: yylval.intval = DECR;
703: return( INCOP );
704: }
705: if( lxchar != '>' ) goto onechar;
706: stwart = FUNNYNAME;
707: yylval.intval=STREF;
708: return( STROP );
709:
710: case A_PL:
711: /* + */
712: if( (lxchar=getchar()) != '+' ) goto onechar;
713: yylval.intval = INCR;
714: return( INCOP );
715:
716: case A_AND:
717: /* & */
718: if( (lxchar=getchar()) != '&' ) goto onechar;
719: return( yylval.intval = ANDAND );
720:
721: case A_OR:
722: /* | */
723: if( (lxchar=getchar()) != '|' ) goto onechar;
724: return( yylval.intval = OROR );
725:
726: case A_LT:
727: /* < */
728: if( (lxchar=getchar()) == '<' ){
729: yylval.intval = LS;
730: return( SHIFTOP );
731: }
732: if( lxchar != '=' ) goto onechar;
733: yylval.intval = LE;
734: return( RELOP );
735:
736: case A_GT:
737: /* > */
738: if( (lxchar=getchar()) == '>' ){
739: yylval.intval = RS;
740: return(SHIFTOP );
741: }
742: if( lxchar != '=' ) goto onechar;
743: yylval.intval = GE;
744: return( RELOP );
745:
746: case A_EQ:
747: /* = */
748: switch( lxchar = getchar() ){
749:
750: case '=':
751: yylval.intval = EQ;
752: return( EQUOP );
753:
754: case '+':
755: yylval.intval = ASG PLUS;
756: break;
757:
758: case '-':
759: yylval.intval = ASG MINUS;
760:
761: warn:
762: if( lxmask[ (lxchar=getchar())+1] & (LEXLET|LEXDIG|LEXDOT) ){
763: werror( "ambiguous assignment: assignment op taken" );
764: }
765: ungetc( lxchar ,stdin);
766: break;
767:
768: case '*':
769: yylval.intval = ASG MUL;
770: goto warn;
771:
772: case '/':
773: yylval.intval = ASG DIV;
774: break;
775:
776: case '%':
777: yylval.intval = ASG MOD;
778: break;
779:
780: case '&':
781: yylval.intval = ASG AND;
782: break;
783:
784: case '|':
785: yylval.intval = ASG OR;
786: break;
787:
788: case '^':
789: yylval.intval = ASG ER;
790: break;
791:
792: case '<':
793: if( (lxchar=getchar()) != '<' ){
794: uerror( "=<%c illegal", lxchar );
795: }
796: yylval.intval = ASG LS;
797: break;
798:
799: case '>':
800: if( (lxchar=getchar()) != '>' ){
801: uerror( "=>%c illegal", lxchar );
802: }
803: yylval.intval = ASG RS;
804: break;
805:
806: default:
807: goto onechar;
808:
809: }
810:
811: return( ASOP );
812:
813: default:
814: cerror( "yylex error, character %03o (octal)", lxchar );
815:
816: }
817:
818: /* ordinarily, repeat here... */
819: cerror( "out of switch in yylex" );
820:
821: }
822:
823: }
824:
825: struct lxrdope {
826: /* dope for reserved, in alphabetical order */
827:
828: char *lxrch; /* name of reserved word */
829: short lxract; /* reserved word action */
830: short lxrval; /* value to be returned */
831: } lxrdope[] = {
832:
833: "asm", AR_A, 0,
834: "auto", AR_CL, AUTO,
835: "break", AR_RW, BREAK,
836: "char", AR_TY, CHAR,
837: "case", AR_RW, CASE,
838: "continue", AR_RW, CONTINUE,
839: "double", AR_TY, DOUBLE,
840: "default", AR_RW, DEFAULT,
841: "do", AR_RW, DO,
842: "extern", AR_CL, EXTERN,
843: "else", AR_RW, ELSE,
844: "enum", AR_E, ENUM,
845: "for", AR_RW, FOR,
846: "float", AR_TY, FLOAT,
847: "fortran", AR_CL, FORTRAN,
848: "goto", AR_RW, GOTO,
849: "if", AR_RW, IF,
850: "int", AR_TY, INT,
851: "long", AR_TY, LONG,
852: "return", AR_RW, RETURN,
853: "register", AR_CL, REGISTER,
854: "switch", AR_RW, SWITCH,
855: "struct", AR_S, 0,
856: "sizeof", AR_RW, SIZEOF,
857: "short", AR_TY, SHORT,
858: "static", AR_CL, STATIC,
859: "typedef", AR_CL, TYPEDEF,
860: "unsigned", AR_TY, UNSIGNED,
861: "union", AR_U, 0,
862: "void", AR_TY, UNDEF, /* tymerge adds FTN */
863: "while", AR_RW, WHILE,
864: "", 0, 0, /* to stop the search */
865: };
866:
867: lxres() {
868: /* check to see of yytext is reserved; if so,
869: /* do the appropriate action and return */
870: /* otherwise, return -1 */
871:
872: register c, ch;
873: register struct lxrdope *p;
874:
875: ch = yytext[0];
876:
877: if( !islower(ch) ) return( -1 );
878:
879: switch( ch ){
880:
881: case 'a':
882: c=0; break;
883: case 'b':
884: c=2; break;
885: case 'c':
886: c=3; break;
887: case 'd':
888: c=6; break;
889: case 'e':
890: c=9; break;
891: case 'f':
892: c=12; break;
893: case 'g':
894: c=15; break;
895: case 'i':
896: c=16; break;
897: case 'l':
898: c=18; break;
899: case 'r':
900: c=19; break;
901: case 's':
902: c=21; break;
903: case 't':
904: c=26; break;
905: case 'u':
906: c=27; break;
907: case 'v':
908: c=29; break;
909: case 'w':
910: c=30; break;
911:
912: default:
913: return( -1 );
914: }
915:
916: for( p= lxrdope+c; p->lxrch[0] == ch; ++p ){
917: if( !strcmp( yytext, p->lxrch ) ){ /* match */
918: switch( p->lxract ){
919:
920: case AR_TY:
921: /* type word */
922: stwart = instruct;
923: yylval.nodep = mkty( (TWORD)p->lxrval, 0, p->lxrval );
924: return( TYPE );
925:
926: case AR_RW:
927: /* ordinary reserved word */
928: return( yylval.intval = p->lxrval );
929:
930: case AR_CL:
931: /* class word */
932: yylval.intval = p->lxrval;
933: return( CLASS );
934:
935: case AR_S:
936: /* struct */
937: stwart = INSTRUCT|SEENAME|TAGNAME;
938: yylval.intval = INSTRUCT;
939: return( STRUCT );
940:
941: case AR_U:
942: /* union */
943: stwart = INUNION|SEENAME|TAGNAME;
944: yylval.intval = INUNION;
945: return( STRUCT );
946:
947: case AR_E:
948: /* enums */
949: stwart = SEENAME|TAGNAME;
950: return( yylval.intval = ENUM );
951:
952: case AR_A:
953: /* asm */
954: asm_esc = 1; /* warn the world! */
955: lxget( ' ', LEXWS );
956: if( getchar() != '(' ) goto badasm;
957: lxget( ' ', LEXWS );
958: if( getchar() != '"' ) goto badasm;
959: # ifndef ONEPASS
960: # ifndef LINT
961: putchar(')');
962: # endif
963: # endif
964: while( (c=getchar()) != '"' ){
965: if( c=='\n' || c==EOF ) goto badasm;
966: # ifndef LINT
967: putchar(c);
968: # endif
969: }
970: lxget( ' ', LEXWS );
971: if( getchar() != ')' ) goto badasm;
972: # ifndef LINT
973: putchar('\n');
974: # endif
975: return( 0 );
976:
977: badasm:
978: uerror( "bad asm construction" );
979: return( 0 );
980:
981: default:
982: cerror( "bad AR_?? action" );
983: }
984: }
985: }
986: return( -1 );
987: }
988:
989: extern int labelno;
990:
991: lxtitle(){
992: /* called after a newline; set linenumber and file name */
993:
994: register c, val;
995: register char *cp, *cq;
996:
997: for(;;){ /* might be several such lines in a row */
998: if( (c=getchar()) != '#' ){
999: if( c != EOF ) ungetc(c,stdin);
1000: #ifndef LINT
1001: if ( lastloc != PROG) return;
1002: cp = ftitle;
1003: cq = ititle;
1004: while ( *cp ) if (*cp++ != *cq++) return;
1005: if ( *cq ) return;
1006: psline();
1007: #endif
1008: return;
1009: }
1010:
1011: lxget( ' ', LEXWS );
1012: val = 0;
1013: for( c=getchar(); isdigit(c); c=getchar() ){
1014: val = val*10+ c - '0';
1015: }
1016: if( c == EOF )
1017: continue;
1018: ungetc( c, stdin );
1019: lineno = val;
1020: lxget( ' ', LEXWS );
1021: if( (c=getchar()) != '\n' && c != EOF ){
1022: for( cp=ftitle; c!=EOF && c!='\n'; c=getchar(),++cp ){
1023: *cp = c;
1024: }
1025: *cp = '\0';
1026: #ifndef LINT
1027: if (ititle[0] == '\0') {
1028: cp = ftitle;
1029: cq = ititle;
1030: while ( *cp )
1031: *cq++ = *cp++;
1032: *cq = '\0';
1033: *--cq = '\0';
1034: #ifndef FLEXNAMES
1035: for ( cp = ititle+1; *(cp-1); cp += 8 ) {
1036: pstab(cp, N_SO);
1037: if (gdebug) printf("0,0,LL%d\n", labelno);
1038: }
1039: #else
1040: pstab(ititle+1, N_SO);
1041: if (gdebug) printf("0,0,LL%d\n", labelno);
1042: #endif
1043:
1044: *cq = '"';
1045: printf("LL%d:\n", labelno++);
1046: }
1047: #endif
1048: }
1049: }
1050: }
1051:
1052: #ifdef FLEXNAMES
1053: #define NSAVETAB 4096
1054: char *savetab;
1055: int saveleft;
1056:
1057: char *
1058: savestr(cp)
1059: register char *cp;
1060: {
1061: register int len;
1062:
1063: len = strlen(cp) + 1;
1064: if (len > saveleft) {
1065: saveleft = NSAVETAB;
1066: if (len > saveleft)
1067: saveleft = len;
1068: savetab = (char *)malloc(saveleft);
1069: if (savetab == 0)
1070: cerror("Ran out of memory (savestr)");
1071: }
1072: strncpy(savetab, cp, len);
1073: cp = savetab;
1074: savetab += len;
1075: saveleft -= len;
1076: return (cp);
1077: }
1078:
1079: /*
1080: * The definition for the segmented hash tables.
1081: */
1082: #define MAXHASH 20
1083: #define HASHINC 1013
1084: struct ht {
1085: char **ht_low;
1086: char **ht_high;
1087: int ht_used;
1088: } htab[MAXHASH];
1089:
1090: char *
1091: hash(s)
1092: char *s;
1093: {
1094: register char **h;
1095: register i;
1096: register char *cp;
1097: struct ht *htp;
1098: int sh;
1099:
1100: /*
1101: * The hash function is a modular hash of
1102: * the sum of the characters with the sum
1103: * doubled before each successive character
1104: * is added.
1105: */
1106: cp = s;
1107: i = 0;
1108: while (*cp)
1109: i = i*2 + *cp++;
1110: sh = (i&077777) % HASHINC;
1111: cp = s;
1112: /*
1113: * There are as many as MAXHASH active
1114: * hash tables at any given point in time.
1115: * The search starts with the first table
1116: * and continues through the active tables
1117: * as necessary.
1118: */
1119: for (htp = htab; htp < &htab[MAXHASH]; htp++) {
1120: if (htp->ht_low == 0) {
1121: register char **hp =
1122: (char **) calloc(sizeof (char **), HASHINC);
1123: if (hp == 0)
1124: cerror("ran out of memory (hash)");
1125: htp->ht_low = hp;
1126: htp->ht_high = htp->ht_low + HASHINC;
1127: }
1128: h = htp->ht_low + sh;
1129: /*
1130: * quadratic rehash increment
1131: * starts at 1 and incremented
1132: * by two each rehash.
1133: */
1134: i = 1;
1135: do {
1136: if (*h == 0) {
1137: if (htp->ht_used > (HASHINC * 3)/4)
1138: break;
1139: htp->ht_used++;
1140: *h = savestr(cp);
1141: return (*h);
1142: }
1143: if (**h == *cp && strcmp(*h, cp) == 0)
1144: return (*h);
1145: h += i;
1146: i += 2;
1147: if (h >= htp->ht_high)
1148: h -= HASHINC;
1149: } while (i < HASHINC);
1150: }
1151: cerror("ran out of hash tables");
1152: }
1153: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.