|
|
1.1 ! root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ ! 2: static char rcsid[]= "$Header: mkboot.c,v 1.1 85/08/22 15:44:31 timo Exp $"; ! 3: ! 4: /* ! 5: * B editor -- Program to create the "boot.h" file (the grammar tables). ! 6: */ ! 7: ! 8: #include "b.h" ! 9: #include "node.h" ! 10: #include "gram.h" ! 11: #include "tabl.h" ! 12: ! 13: #include <ctype.h> ! 14: ! 15: ! 16: /* ! 17: * Test whether sym is in the given class. ! 18: */ ! 19: ! 20: Visible bool ! 21: isinclass(sym, ci) ! 22: int sym; ! 23: struct classinfo *ci; ! 24: { ! 25: classptr cp; ! 26: ! 27: Assert(ci && ci->c_class); ! 28: if (sym == Hole) ! 29: return !isinclass(Optional, ci); ! 30: for (cp = ci->c_class; *cp; ++cp) ! 31: if (sym == *cp) ! 32: return Yes; ! 33: return No; ! 34: } ! 35: ! 36: ! 37: main() ! 38: { ! 39: int sym; ! 40: int nch; ! 41: struct classinfo **cp; ! 42: struct classinfo *sp; ! 43: ! 44: printf("/* boot.h -- data file for grammar tables. */\n\n"); ! 45: ! 46: /* Check the representations. ! 47: The code assumes Optional and Hole are the last symbols ! 48: in the table, i.e. the first processed by the loop. */ ! 49: ! 50: for (sym = TABLEN-1; sym >= 0; --sym) { ! 51: if (table[sym].r_symbol != sym) { ! 52: if (sym != Hole && sym != Optional ! 53: && table[sym].r_symbol == 0) ! 54: continue; /* Disabled table entry */ ! 55: syserr("initgram: table order (%s=%d, should be %d)", ! 56: table[sym].r_name, table[sym].r_symbol, sym); ! 57: } ! 58: cp = table[sym].r_class; ! 59: for (nch = 0; nch < MAXCHILD && (sp = cp[nch]); ++nch) ! 60: ; ! 61: ckrepr(table[sym].r_repr, nch); ! 62: } ! 63: ! 64: initcodes(); ! 65: initclasses(); ! 66: dumptable(); ! 67: exit(0); ! 68: } ! 69: ! 70: ! 71: /* ! 72: * Check a representation array (subroutine for initgram). ! 73: */ ! 74: ! 75: Hidden Procedure ! 76: ckrepr(rp, nch) ! 77: string *rp; ! 78: int nch; ! 79: { ! 80: string cp; ! 81: int i; ! 82: int ich; ! 83: ! 84: for (ich = 0; ich <= nch; ++ich) { ! 85: cp = rp[ich]; ! 86: if (!cp) ! 87: continue; ! 88: for (i = 0; cp[i]; ++i) { ! 89: switch (cp[i]) { ! 90: case '\n': ! 91: case '\r': ! 92: if (i || ich) ! 93: syserr("initgram (ckrepr): badly placed \\n/\\r"); ! 94: break; ! 95: case '\t': ! 96: case '\b': ! 97: if (cp[i+1]) ! 98: syserr("initgram (ckrepr): badly placed \\t/\\b"); ! 99: break; ! 100: default: ! 101: if (cp[i] < ' ' || cp[i] >= 0177) ! 102: syserr("initgram (ckrepr): illegal control char"); ! 103: } ! 104: } ! 105: } ! 106: } ! 107: ! 108: ! 109: /* ! 110: * Compaction scheme for characters to save space in grammar tables ! 111: * by combining characters with similar properties (digits, l.c. letters). ! 112: */ ! 113: ! 114: #define RANGE 128 /* ASCII characters are in {0 .. RANGE-1} */ ! 115: ! 116: Visible char code_array[RANGE]; ! 117: Visible char invcode_array[RANGE]; ! 118: Visible int lastcode; ! 119: ! 120: Hidden Procedure ! 121: initcodes() ! 122: { ! 123: int c; ! 124: ! 125: code_array['\n'] = ++lastcode; ! 126: invcode_array[lastcode] = '\n'; ! 127: for (c = ' '; c <= '0'; ++c) { ! 128: code_array[c] = ++lastcode; ! 129: invcode_array[lastcode] = c; ! 130: } ! 131: for (; c <= '9'; ++c) ! 132: code_array[c] = lastcode; ! 133: for (; c <= 'a'; ++c) { ! 134: code_array[c] = ++lastcode; ! 135: invcode_array[lastcode] = c; ! 136: } ! 137: for (; c <= 'z'; ++c) ! 138: code_array[c] = lastcode; ! 139: for (; c < RANGE; ++c) { ! 140: code_array[c] = ++lastcode; ! 141: invcode_array[lastcode] = c; ! 142: } ! 143: } ! 144: ! 145: ! 146: /* ! 147: * Initialization routine for the 'struct classinfo' stuff. ! 148: * ! 149: * "Suggestion" is skipped: ! 150: * what can be inserted there is not computed from this table. ! 151: */ ! 152: ! 153: Hidden Procedure ! 154: initclasses() ! 155: { ! 156: int i; ! 157: int j; ! 158: struct table *tp; ! 159: ! 160: for (i = 0; i < TABLEN; ++i) { ! 161: tp = &table[i]; ! 162: if (tp->r_symbol != i || i == Suggestion) ! 163: continue; /* Dead entry */ ! 164: for (j = 0; j < MAXCHILD && tp->r_class[j]; ++j) { ! 165: if (!tp->r_class[j]->c_insert) ! 166: defclass(tp->r_class[j]); ! 167: } ! 168: } ! 169: } ! 170: ! 171: classptr makelist(); /* Forward */ ! 172: ! 173: Hidden Procedure ! 174: defclass(p) ! 175: struct classinfo *p; ! 176: { ! 177: int c; ! 178: struct table *tp; ! 179: classptr cp; ! 180: classptr cp1; ! 181: classelem insert[1024]; ! 182: classelem append[1024]; ! 183: classelem join[1024]; ! 184: int inslen = 0; ! 185: int applen = 0; ! 186: int joinlen = 0; ! 187: string *rp; ! 188: int fw1; ! 189: ! 190: cp = p->c_class; ! 191: Assert(cp); ! 192: ! 193: for (; *cp; ++cp) { ! 194: if (*cp == Optional) ! 195: continue; ! 196: if (*cp >= TABLEN) { /* Insert direct lexical item */ ! 197: for (c = 1; c <= lastcode; ++c) { ! 198: if (maystart(Invcode(c), *cp)) { ! 199: Assert(inslen+3 < sizeof insert / sizeof insert[0]); ! 200: insert[inslen] = c; ! 201: insert[inslen+1] = *cp; ! 202: inslen += 2; ! 203: } ! 204: } ! 205: continue; ! 206: } ! 207: tp = &table[*cp]; ! 208: rp = tp->r_repr; ! 209: if (!Fw_zero(rp[0])) { /* Insert fixed text */ ! 210: c = Code(rp[0][0]); ! 211: Assert(inslen+3 < sizeof insert / sizeof insert[0]); ! 212: insert[inslen] = c; ! 213: insert[inslen+1] = *cp; ! 214: inslen += 2; ! 215: continue; ! 216: } ! 217: Assert(tp->r_class[0]); ! 218: cp1 = tp->r_class[0]->c_class; ! 219: Assert(cp1); ! 220: for (; *cp1; ++cp1) { ! 221: if (*cp1 < TABLEN) ! 222: continue; ! 223: for (c = 1; c <= lastcode; ++c) { /* Insert indir. lex. items */ ! 224: if (maystart(Invcode(c), *cp1)) { ! 225: Assert(inslen+3 < sizeof insert / sizeof insert[0]); ! 226: insert[inslen] = c; ! 227: insert[inslen+1] = *cp; ! 228: inslen += 2; ! 229: } ! 230: } ! 231: } ! 232: fw1 = Fwidth(rp[1]); ! 233: if (fw1) { /* Append */ ! 234: c = rp[1][0]; ! 235: Assert(c > 0 && c < RANGE); ! 236: if (c == ' ') { ! 237: c = rp[1][1]; ! 238: if (!c || c == '\b' || c == '\t') ! 239: c = ' '; ! 240: else ! 241: c |= 0200; ! 242: } ! 243: Assert(applen+3 < sizeof append / sizeof append[0]); ! 244: append[applen] = c; ! 245: append[applen+1] = *cp; ! 246: applen += 2; ! 247: } ! 248: if ((!fw1 || fw1 == 1 && rp[1][0] == ' ') ! 249: && tp->r_class[1]) { /* Join */ ! 250: Assert(joinlen+3 < sizeof join / sizeof join[0]); ! 251: join[joinlen] = 1 + fw1; ! 252: join[joinlen+1] = *cp; ! 253: joinlen += 2; ! 254: } ! 255: } ! 256: ! 257: Assert(inslen); /* Dead alley */ ! 258: insert[inslen] = 0; ! 259: p->c_insert = makelist(insert, inslen + 1); ! 260: if (applen) { ! 261: append[applen] = 0; ! 262: p->c_append = makelist(append, applen + 1); ! 263: } ! 264: if (joinlen) { ! 265: join[joinlen] = 0; ! 266: p->c_join = makelist(join, joinlen + 1); ! 267: } ! 268: } ! 269: ! 270: Hidden classptr ! 271: makelist(list, len) ! 272: classptr list; ! 273: int len; ! 274: { ! 275: classptr cp = ! 276: (classptr) malloc((unsigned) (len*sizeof(classelem))); ! 277: int i; ! 278: ! 279: if (!cp) ! 280: syserr("makelist: malloc"); ! 281: for (i = 0; i < len; ++i, ++list) ! 282: cp[i] = *list; ! 283: #ifndef NDEBUG ! 284: if (index(cp, '\0') != cp+len-1) ! 285: printf("makelist: zero in string!\n"); ! 286: #endif ! 287: return cp; ! 288: } ! 289: ! 290: #define MAXLOOKUP 1000 ! 291: ! 292: Hidden struct classinfo **known; ! 293: Hidden int nknown; ! 294: ! 295: Hidden Procedure ! 296: dumptable() ! 297: { ! 298: int sym; ! 299: ! 300: getclassinfos(); ! 301: printf("Hidden struct table b_grammar[%d] = {\n", TABLEN); ! 302: for (sym= 0; sym < TABLEN; ++sym) ! 303: dumpentry(table+sym); ! 304: printf("};\n"); ! 305: free(known); ! 306: } ! 307: ! 308: Hidden Procedure ! 309: getclassinfos() ! 310: { ! 311: int sym, k; ! 312: ! 313: known= (struct classinfo **) malloc(MAXLOOKUP * sizeof(struct classinfo*)); ! 314: if (known == NULL) ! 315: syserr("getclassinfos: can't malloc 'known' array"); ! 316: nknown= 0; ! 317: printf("Hidden struct classinfo cl[] = {\n"); ! 318: for (sym= 0; sym < TABLEN; ++sym) { ! 319: for (k= 0; k < MAXCHILD; ++k) ! 320: lookup(table[sym].r_class[k]); ! 321: } ! 322: printf("};\n\n"); ! 323: } ! 324: ! 325: Hidden int ! 326: lookup(ci) ! 327: struct classinfo *ci; ! 328: { ! 329: int k; ! 330: ! 331: if (ci == NULL) ! 332: return -1; ! 333: for (k= 0; k < nknown; ++k) { ! 334: if (known[k] == ci) ! 335: return k; ! 336: } ! 337: if (k < MAXLOOKUP) { ! 338: ++nknown; ! 339: known[k]= ci; ! 340: printf("/*%d*/", k); ! 341: dumpclassinfo(ci); ! 342: } ! 343: } ! 344: ! 345: Hidden Procedure ! 346: dumpclassinfo(ci) ! 347: struct classinfo *ci; ! 348: { ! 349: printf("\t{"); ! 350: dumpstring(ci->c_class); ! 351: printf("\n\t"); ! 352: dumpstring(ci->c_insert); ! 353: printf("\n\t"); ! 354: dumpstring(ci->c_append); ! 355: printf("\n\t"); ! 356: dumpstring(ci->c_join); ! 357: printf("},\n"); ! 358: } ! 359: ! 360: Hidden Procedure ! 361: dumpentry(p) ! 362: struct table *p; ! 363: { ! 364: int k; ! 365: ! 366: printf("\t{%2d, ", p->r_symbol); ! 367: dumpstring(p->r_name); ! 368: printf(" {"); ! 369: for (k= 0; k <= MAXCHILD; ++k) ! 370: dumpstring(p->r_repr[k]); ! 371: printf("}, {"); ! 372: for (k= 0; k < MAXCHILD; ++k) ! 373: refclassinfo(p->r_class[k]); ! 374: printf("}, 0},\n"); ! 375: } ! 376: ! 377: Hidden Procedure ! 378: dumpstring(s) ! 379: string s; ! 380: { ! 381: char c; ! 382: ! 383: if (s == NULL) { ! 384: printf("0, "); ! 385: return; ! 386: } ! 387: printf("\""); ! 388: for (; (c= *s) != '\0'; ++s) { ! 389: if (c >= ' ' && c < 0177) { ! 390: if (c == '\\' || c == '"') ! 391: printf("\\"); ! 392: printf("%c", c); ! 393: } ! 394: else if (c == '\t') ! 395: printf("\\t"); ! 396: else if (c == '\b') ! 397: printf("\\b"); ! 398: else ! 399: printf("\\%03o", c&0377); ! 400: } ! 401: printf("\", "); ! 402: } ! 403: ! 404: Hidden Procedure ! 405: refclassinfo(ci) ! 406: struct classinfo ci; ! 407: { ! 408: int k= lookup(ci); ! 409: ! 410: if (k >= 0) ! 411: printf("&cl[%d], ", k); ! 412: else ! 413: printf("0, "); ! 414: } ! 415: ! 416: ! 417: /* ! 418: * Yield the width of a piece of fixed text as found in a node's repr, ! 419: * excluding \b or \t. If \n or \r is found, -1 is returned. ! 420: * It assumes that \n or \r only occur as first ! 421: * character, and \b or \t only as last. ! 422: */ ! 423: ! 424: Visible int ! 425: fwidth(str) ! 426: register string str; ! 427: { ! 428: register int c; ! 429: register int n = 0; ! 430: ! 431: if (!str) ! 432: return 0; ! 433: c = str[0]; ! 434: if (c == '\r' || c == '\n') ! 435: return -1; ! 436: for (; c; c = *++str) ! 437: ++n; ! 438: if (n > 0) { ! 439: c = str[-1]; ! 440: if (c == '\t' || c == '\b') ! 441: --n; ! 442: } ! 443: return n; ! 444: } ! 445: ! 446: ! 447: Visible Procedure ! 448: syserr(fmt, a1, a2, a3, a4, a5) ! 449: string fmt; ! 450: { ! 451: fprintf(stderr, "mkboot system error:\n"); ! 452: fprintf(stderr, fmt, a1, a2, a3, a4, a5); ! 453: fprintf(stderr, "\n"); ! 454: exit(1); ! 455: } ! 456: ! 457: ! 458: Visible Procedure ! 459: asserr(file, line) ! 460: string file; ! 461: int line; ! 462: { ! 463: syserr("assertion error: %s, line %d", file, line); ! 464: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.