Annotation of 43BSD/contrib/B/src/bed/mkboot.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.