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: }

Defined functions

asserr defined in line 458; used 1 times
ckrepr defined in line 75; used 1 times
  • in line 61
defclass defined in line 173; used 1 times
dumpclassinfo defined in line 345; used 1 times
dumpentry defined in line 360; used 1 times
dumpstring defined in line 377; used 6 times
dumptable defined in line 295; used 1 times
  • in line 66
fwidth defined in line 424; never used
getclassinfos defined in line 308; used 1 times
initclasses defined in line 153; used 1 times
  • in line 65
initcodes defined in line 120; used 1 times
  • in line 64
isinclass defined in line 20; used 1 times
  • in line 29
lookup defined in line 325; used 2 times
main defined in line 37; never used
makelist defined in line 270; used 4 times
refclassinfo defined in line 404; used 1 times

Defined variables

code_array defined in line 116; used 6 times
invcode_array defined in line 117; used 4 times
known defined in line 292; used 5 times
lastcode defined in line 118; used 12 times
nknown defined in line 293; used 3 times
rcsid defined in line 2; never used

Defined macros

MAXLOOKUP defined in line 290; used 2 times
RANGE defined in line 114; used 4 times
Last modified: 1985-08-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2005
Valid CSS Valid XHTML 1.0 Strict