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