|
|
1.1 root 1: #include <stdio.h>
2: #include "efix.h"
3: #define Hlen 4091
4: #define HGULP 1020
5: #define SGULP 8092
6: extern char *strcpy();
7:
8: char *
9: alloc(x)
10: unsigned x;
11: {
12: extern char *malloc();
13: char *s;
14: s = malloc(x);
15: if (!s) {
16: fprintf(stderr, "%s: malloc failure!\n", progname);
17: exit(1);
18: }
19: return s;
20: }
21:
22: struct HashHeader {
23: struct Hash *next, *prev;
24: } maintab[Hlen], memtab[Hlen];
25:
26: struct Hash {
27: struct HashHeader hh;
28: char *name;
29: char *type;
30: struct Hash *dup;
31: int lev;
32: } *halloc_next, *halloc_last, *lasthash;
33:
34: /* type values:
35: * static, auto, extern, register: i
36: * char, double, float, int, long, short, unsigned, void: i
37: * enum: e
38: * struct, union: a
39: * typedef: t
40: * struct tag, union tag, typedefed name: T{type}
41: */
42:
43: char *salloc_next, *salloc_last;
44: struct SALLOC {
45: struct SALLOC *next;
46: char *last;
47: char block[SGULP];
48: } *Salloc_block;
49: struct HALLOC {
50: struct HALLOC *next, *prev;
51: struct Hash block[HGULP];
52: } *Halloc_block;
53:
54: struct Context {
55: struct Context *next, *prev;
56: struct SALLOC *Sblock;
57: char *snext, *slast;
58: struct HALLOC *Hblock;
59: struct Hash *hnext;
60: } *context;
61: int levnow;
62:
63: new_context()
64: {
65: struct Context *C;
66: ++levnow;
67: if (!context || !(C = context->next)) {
68: C = (struct Context *)alloc(sizeof(struct Context));
69: C->next = 0;
70: if (context)
71: context->next = C;
72: C->prev = context;
73: }
74: context = C;
75: C->Sblock = Salloc_block;
76: C->Hblock = Halloc_block;
77: C->snext = salloc_next;
78: C->slast = salloc_last;
79: C->hnext = halloc_next;
80: }
81:
82: end_context()
83: {
84: struct Hash *h, *h0, *h00, *h1;
85: struct HALLOC *H;
86: struct Context *C;
87:
88: --levnow;
89: C = context;
90: context = C->prev;
91: if (!C || levnow < 0)
92: scream("too many end_context's");
93: Salloc_block = C->Sblock;
94: salloc_next = C->snext;
95: salloc_last = C->slast;
96: h00 = C->hnext;
97: if (H = Halloc_block) {
98: h0 = H->block;
99: h = halloc_next;
100: while(h != h00) {
101: if (--h == h0) {
102: H = H->prev;
103: h0 = H->block;
104: h = h0 + HGULP;
105: continue;
106: }
107: h1 = h->hh.next;
108: h1->hh.prev = h->hh.prev;
109: h->hh.prev->hh.next = h1;
110: }
111: }
112: Halloc_block = C->Hblock;
113: halloc_next = h00;
114: }
115:
116: struct Hash *
117: hash(s, ht)
118: register char *s;
119: struct HashHeader *ht;
120: {
121: register x = 0, c;
122: register struct Hash *h, *h0;
123: char *s0 = s;
124:
125: while(c = *s++) {
126: if (x & 1)
127: x = 0x40000000 | (x>>1) ^ c;
128: else
129: x = (x>>1) ^ c;
130: }
131: x %= Hlen;
132: lasthash = h0 = (struct Hash *) (ht + x);
133: s = s0;
134: for(h = h0->hh.next; h != h0; h = h->hh.next)
135: if (!strcmp(s,h->name))
136: return h;
137: return 0;
138: }
139:
140: char *
141: salloc(s)
142: char *s;
143: {
144: unsigned x;
145: char *t;
146: struct SALLOC *S;
147:
148: x = strlen(s) + 1;
149: t = salloc_next;
150: if ((salloc_next += x) > salloc_last) {
151: if (Salloc_block && (S = Salloc_block->next)) {
152: if (S->last - S->block < x)
153: scream("Huge string in salloc");
154: }
155: else {
156: S = (struct SALLOC *)alloc(x + sizeof(struct SALLOC));
157: if (Salloc_block)
158: Salloc_block->next = S;
159: S->last = S->block + x + SGULP;
160: S->next = 0;
161: }
162: t = S->block;
163: salloc_next = t + x;
164: salloc_last = S->last;
165: Salloc_block = S;
166: }
167: return strcpy(t, s);
168: }
169:
170: struct Hash *
171: newhash(s,t)
172: char *s, *t;
173: {
174: struct Hash *h, *h1;
175: struct HALLOC *H;
176:
177: if ((h = halloc_next++) >= halloc_last) {
178: if (!Halloc_block || !(H = Halloc_block->next)) {
179: H = (struct HALLOC *)
180: alloc(sizeof(struct HALLOC));
181: H->next = 0;
182: H->prev = Halloc_block;
183: }
184: Halloc_block = H;
185: h = H->block;
186: halloc_next = h + 1;
187: halloc_last = h + HGULP;
188: }
189: h->name = s;
190: h->type = t;
191: h->lev = levnow;
192: h->hh.next = h1 = lasthash->hh.next;
193: h1->hh.prev = h;
194: h->hh.prev = lasthash;
195: lasthash->hh.next = h;
196: return h;
197: }
198:
199: struct Tok Toks[3];
200: char isdcl[128];
201:
202: setup()
203: {
204: int i;
205: struct HashHeader *h;
206: static char *keywds[] = {
207: "auto", "i",
208: "char", "i",
209: "double", "i",
210: "enum", "e",
211: "extern", "i",
212: "float", "i",
213: "int", "i",
214: "long", "i",
215: "register", "i",
216: "short", "i",
217: "static", "i",
218: "struct", "a",
219: "typedef", "t",
220: "union", "a",
221: "unsigned", "i",
222: "void", "i",
223: 0, 0};
224: char **k, *s;
225:
226: Toks[0].next = Toks + 1; Toks[0].prev = Toks + 2;
227: Toks[1].next = Toks + 2; Toks[1].prev = Toks;
228: Toks[2].next = Toks; Toks[2].prev = Toks + 1;
229: for(i = 0; i < 3; i++) Toks[i].inlevel = 1;
230: T = Toks;
231: for(h = maintab, i = 0; i < Hlen; ++i, ++h)
232: h->next = h->prev = (struct Hash *)h;
233: for(h = memtab, i = 0; i < Hlen; ++i, ++h)
234: h->next = h->prev = (struct Hash *)h;
235:
236: for(k = keywds; *k; k += 2) {
237: hash(*k, maintab);
238: newhash(k[0], k[1]);
239: }
240: for(s = "aeitT"; *s; ++s)
241: isdcl[*s] = 1;
242: }
243:
244: process()
245: {
246: int t;
247: struct Tok *T1;
248:
249: setup();
250:
251: while((t = token(0)) != FEND) {
252: if (t == SYMBOL)
253: dcl();
254: else if (t != ';') {
255: squawk("expected declaration");
256: do token(2);
257: while(t != ';');
258: }
259: }
260: done:
261: for(T1 = T;;) {
262: T1 = T1->next;
263: if (!T1->inlevel)
264: printf("%s%s", T1->white, T1->tok);
265: if (T1 == T)
266: break;
267: }
268: }
269:
270: char *
271: memname()
272: {
273: int pars = 0;
274: char *s;
275: int t;
276:
277: for(t = T->type; ; t = token(2)) {
278: switch(t) {
279: case '(': ++pars;
280: case '*': continue;
281: case ':':
282: if (pars)
283: scream("unexpected :");
284: getexp();
285: return 0;
286: default: break;
287: }
288: break;
289: }
290: if (t != SYMBOL)
291: scream("expected * ( : or symbol") /*)*/;
292: s = salloc(T->tok);
293: for(;;) {
294: switch(token(2)) {
295: case '(':
296: case '[':
297: ++pars;
298: continue;
299: case ')':
300: case ']':
301: --pars;
302: continue;
303: case ':':
304: if (!pars) {
305: getexp();
306: break;
307: }
308: case ';':
309: break;
310: case ',':
311: if (pars <= 0)
312: break;
313: default:
314: continue;
315: }
316: break;
317: }
318: if (pars)
319: squawk("bad paren count in memname");
320: return s;
321: }
322:
323: char *
324: sdcl(tag)
325: char *tag;
326: {
327: int t, typed;
328: char buf[256], *m, *s;
329: struct Hash *h, *h1;
330: static int anon;
331: char *b, *be = buf + sizeof(buf);
332:
333: b = adjoin(buf,be,tag);
334: *b++ = *T->tok; /* 's' or 'u' */
335: t = token(2);
336: if (t == SYMBOL) {
337: adjoin(b,be,T->tok);
338: t = token(2);
339: }
340: else
341: sprintf(b, "#%d", ++anon);
342: s = salloc(buf);
343: if (t != '{') /*}*/ {
344: return s;
345: }
346:
347: /* struct foo {...} -- process the ... */
348:
349: for(t = token(2); /*{*/ t != '}'; t = token(2)) {
350: for(typed = 0; t == SYMBOL; t = token(2), typed = 1) {
351: h = hash(T->tok, maintab);
352: if (h) switch(*h->type) {
353: case 'a':
354: case 'e':
355: t = token(2);
356: if (t != SYMBOL)
357: scream("expected tag");
358: case 'i':
359: case 'T':
360: continue;
361: case 't':
362: scream("typedef within struct!");
363: }
364: break;
365: }
366: if (!typed)
367: scream("no type!");
368: if (t != ';')
369: for(; ; token(2)) {
370: if (m = memname()) {
371: h = hash(m, memtab);
372: h1 = newhash(m, s);
373: h1->dup = h;
374: }
375: switch(T->type) {
376: case ',': continue;
377: case ';': break;
378: default:
379: scream("expected ; or ,");
380: }
381: break;
382: }
383: }
384: token(2);
385: return s;
386: }
387:
388: dcl()
389: {
390: struct Hash *h;
391: char buf[256], *sym;
392: int pars = 0, t, typed = 0;
393: char *b = buf, *buf1 = buf, *be = buf + sizeof(buf), *tag = "";
394:
395: for(t = SYMBOL; t == SYMBOL; t = token(2)) {
396: h = hash(T->tok, maintab);
397: if (h) switch(*h->type) {
398: case 'T':
399: tag = h->type + 1;
400: typed = 1;
401: continue;
402: case 'a': /* aggregate -- struct or union */
403: tag = sdcl(tag);
404: typed = 1;
405: t = T->type;
406: goto havetag;
407: case 'e':
408: do t = token(2);
409: while(t != ';');
410: return;
411: case 'i':
412: typed = 1;
413: continue;
414: case 't':
415: typed = 0;
416: *buf = 'T';
417: b = buf1 = buf + 1;
418: continue;
419: }
420: break;
421: }
422: havetag:
423: for(; t != ';'; t = token(2)) {
424: if (t != SYMBOL)
425: switch(t) {
426: case '(':
427: ++pars;
428: case '*':
429: *b++ = t;
430: continue;
431: default:
432: scream("expected symbol, ( or *" /*)*/);
433: }
434: sym = salloc(T->tok);
435: b = adjoin(b,be,tag);
436: while(pars > 0) {
437: switch(t = token(2)) {
438: case '(':
439: case '[':
440: ++pars;
441: break;
442: case ')':
443: case ']':
444: --pars;
445: break;
446: default:
447: scream("expected ( [ ] or )");
448: }
449: *b++ = t;
450: }
451: if (pars < 0)
452: scream("negative paren count!");
453: t = token(2);
454: if (t == '(' /*)*/) {
455: adjoin(b,be,"()");
456: if ((h = hash(sym, maintab))) {
457: if (h->lev == levnow && strcmp(buf,h->type)) {
458: badtype:
459: squawk("wrong type!");
460: fprintf(stderr, "expected %s, got %s\n",
461: h->type, buf);
462: exit(1);
463: }
464: }
465: else newhash(sym,salloc(buf));
466:
467: /* start of a function body? */
468:
469: switch(t = token(2)) {
470: case SYMBOL:
471: function();
472: return;
473: case /*(*/ ')':
474: t = token(2);
475: if (t == '{'/*}*/) {
476: function();
477: return;
478: }
479: break;
480: default:
481: scream(/*(*/"expected symbol or )");
482: }
483: }
484: else {
485: if (!typed)
486: scream("expected type or function prologue");
487: if (t == '['/*]*/)
488: for(; ; t = token(2)) {
489: switch(t) {
490: case '[':
491: if (!pars)
492: adjoin(b,be,"[]");
493: case '(':
494: ++pars;
495: continue;
496: case ']':
497: case ')':
498: --pars;
499: continue;
500: default:
501: if (pars)
502: continue;
503: }
504: break;
505: }
506: if ((h = hash(sym, maintab))) {
507: if (h->lev == levnow && strcmp(buf,h->type))
508: goto badtype;
509: }
510: else newhash(sym,salloc(buf));
511: }
512: switch(t) {
513: case ',':
514: break;
515: case ';':
516: return;
517: case '=':
518: t = getexp();
519: if (t == ';')
520: return;
521: break;
522: default:
523: scream("expected , ; or =");
524: }
525: b = buf1;
526: }
527: }
528:
529: doarrow()
530: {
531: struct Tok *T0, *T1;
532: int t;
533: struct Hash *h, *h0;
534: char *s, *what;
535:
536: T0 = T->prev;
537: if (T0->type != SYMBOL || T0->inlevel)
538: return;
539: untok = t = token(2);
540: if (t != SYMBOL)
541: return;
542: T1 = T;
543: if (!(h = hash(T1->tok, memtab))
544: || !(h0 = hash(T0->tok, maintab)))
545: return;
546: if (*h0->type == '*' && !strcmp(h0->type+1, h->type))
547: return;
548: T0->inlevel = 1;
549: s = h->type;
550: what = *s++ == 's' ? "struct" : "union";
551: if (!h->dup)
552: printf("%s((%s %s *)%s)", T0->white, what, s, T0->tok);
553: else {
554: printf("%s((%s %s /*"/*))*/, T0->white, what, s);
555: if (verbose) {
556: squawk("ambiguous tag");
557: fprintf(stderr, "%s %s", what, s);
558: }
559: while(h = h->dup) {
560: s = h->type;
561: what = *s++ == 's' ? "struct" : "union";
562: printf("|| %s %s", what, s);
563: if (verbose)
564: fprintf(stderr, " || %s %s", what, s);
565: }
566: printf(/*((*/" */ *)%s)", T0->tok);
567: }
568: }
569:
570: getexp()
571: {
572: int brcnt = 0, t;
573:
574: for(;;) switch(t = token(2)) {
575: case ';':
576: if (brcnt)
577: scream("unclosed braces!");
578: /* no break */
579: case ',':
580: if (!brcnt)
581: return t;
582: break;
583: case ARROW:
584: doarrow();
585: break;
586: case '(':
587: case '{':
588: ++brcnt;
589: break;
590: case '}':
591: case ')':
592: --brcnt;
593: break;
594: }
595: }
596:
597: function()
598: {
599: int paren, t;
600: struct Hash *h;
601: /*debug*/static int zork; extern int lineno;
602:
603: if (levnow)
604: scream("inner function def!");
605: new_context();
606: if (T->type == SYMBOL) {
607: while((t = token(2)) != /*(*/ ')') {
608: if (t != ',')
609: scream(/*(*/"expected ) or ,");
610: if (token(2) != SYMBOL)
611: scream("expected dummy arg");
612: }
613: while((t = token(2)) == SYMBOL)
614: dcl();
615: if (t != '{'/*}*/)
616: scream(/*{*/"expected }");
617: }
618: new_context();
619: paren = 0;
620: top:
621: for(;;) {
622: switch(t = token(2)) {
623: case ';':
624: continue;
625: case '{':
626: new_context();
627: continue;
628: case '}':
629: end_context();
630: if (levnow == 1) {
631: end_context();
632: return;
633: }
634: continue;
635: case '(': /*)*/
636: paren++;
637: break;
638: case SYMBOL:
639: if ((h = hash(T->tok,maintab))
640: && isdcl[*h->type]) {
641: dcl();
642: continue;
643: }
644: }
645: /* fall thru for non declaration stmt */
646: for(;;) {
647: /*debug*/ if (lineno == zork)
648: /*debug*/ printf("");
649: switch(t = token(2)) {
650: case ARROW:
651: doarrow();
652: continue;
653: case ';':
654: if (!paren)
655: goto top;
656: continue;
657: case '(':
658: ++paren;
659: continue;
660: case ')':
661: if (--paren < 0)
662: scream("bad paren count");
663: continue;
664: case '{':
665: if (paren)
666: scream("unexpected {");
667: new_context();
668: goto top;
669: case '}':
670: scream("unexpected }");
671: }
672: }
673: }
674: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.