Annotation of 43BSD/contrib/B/src/bed/gram.c, revision 1.1

1.1     ! root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
        !             2: static char rcsid[] = "$Header: gram.c,v 2.5 85/08/22 16:03:16 timo Exp $";
        !             3: 
        !             4: /*
        !             5:  * B editor -- All routines referencing the grammar table are in this file.
        !             6:  */
        !             7: 
        !             8: #include "b.h"
        !             9: #include "feat.h"
        !            10: #include "bobj.h"
        !            11: #include "node.h"
        !            12: #include "gram.h"
        !            13: #include "supr.h"
        !            14: #include "tabl.h"
        !            15: 
        !            16: extern bool dflag;
        !            17: 
        !            18: #include <ctype.h>
        !            19: 
        !            20: 
        !            21: /*
        !            22:  * Test whether sym is in the given class.
        !            23:  */
        !            24: 
        !            25: Visible bool
        !            26: isinclass(sym, ci)
        !            27:        register int sym;
        !            28:        struct classinfo *ci;
        !            29: {
        !            30:        register classptr cp;
        !            31: 
        !            32:        Assert(ci && ci->c_class);
        !            33:        if (sym == Hole)
        !            34:                return !isinclass(Optional, ci);
        !            35:        for (cp = ci->c_class; *cp; ++cp)
        !            36:                if (sym == *cp)
        !            37:                        return Yes;
        !            38:        return No;
        !            39: }
        !            40: 
        !            41: 
        !            42: /*
        !            43:  * Deliver the representation array for the given node.
        !            44:  * If the node is actually just a "text" value, construct
        !            45:  * one in static storage -- which is overwritten at each call.
        !            46:  * In this case there are two deficiencies: the next call to
        !            47:  * noderepr which uses the same feature overwrites the reply
        !            48:  * value of the previous call, AND if the text value itself
        !            49:  * is changed, the representation may change, too.
        !            50:  * In practical use this is no problem at all, however.
        !            51:  */
        !            52: 
        !            53: Visible string *
        !            54: noderepr(n)
        !            55:        register node n;
        !            56: {
        !            57:        register int sym;
        !            58: 
        !            59:        if (n && Type(n) == Tex) {
        !            60:                static string buf[2];
        !            61:                buf[0] = Str((value)n);
        !            62:                return buf;
        !            63:        }
        !            64:        sym = symbol(n);
        !            65:        return table[sym].r_repr;
        !            66: }
        !            67: 
        !            68: 
        !            69: /*
        !            70:  * Deliver the prototype node for the given symbol.
        !            71:  */
        !            72: 
        !            73: Visible node
        !            74: gram(sym)
        !            75:        register int sym;
        !            76: {
        !            77:        Assert(sym == 0 || sym > 0 && sym < TABLEN && table[sym].r_symbol);
        !            78:        return table[sym].r_node;
        !            79: }
        !            80: 
        !            81: #ifdef SAVEBUF
        !            82: 
        !            83: /*
        !            84:  * Deliver the name of a symbol.
        !            85:  */
        !            86: 
        !            87: Visible string
        !            88: symname(sym)
        !            89:        int sym;
        !            90: {
        !            91:        static char buf[20];
        !            92: 
        !            93:        if (sym >= 0 && sym < TABLEN && table[sym].r_name)
        !            94:                return table[sym].r_name;
        !            95:        sprintf(buf, "%d", sym);
        !            96:        return buf;
        !            97: }
        !            98: 
        !            99: 
        !           100: /*
        !           101:  * Find the symbol corresponding to a given name.
        !           102:  * Return -1 if not found.
        !           103:  */
        !           104: 
        !           105: Visible int
        !           106: nametosym(str)
        !           107:        register string str;
        !           108: {
        !           109:        register int sym;
        !           110:        register string name;
        !           111: 
        !           112:        for (sym = 0; sym < TABLEN; ++sym) {
        !           113:                name = table[sym].r_name;
        !           114:                if (name && Strequ(name, str))
        !           115:                        return sym;
        !           116:        }
        !           117:        return -1;
        !           118: }
        !           119: 
        !           120: #endif SAVEBUF
        !           121: 
        !           122: /*
        !           123:  * Test whether `sym' may replace the node in the path `p'.
        !           124:  */
        !           125: 
        !           126: Visible bool
        !           127: allowed(p, sym)
        !           128:        register path p;
        !           129:        register int sym;
        !           130: {
        !           131:        register path pa = parent(p);
        !           132:        register int ich = ichild(p);
        !           133:        register int sympa = pa ? symbol(tree(pa)) : Rootsymbol;
        !           134: 
        !           135:        Assert(sympa >= 0 && sympa < TABLEN && ich > 0 && ich <= MAXCHILD);
        !           136:        return isinclass(sym, table[sympa].r_class[ich-1]);
        !           137: }
        !           138: 
        !           139: 
        !           140: /*
        !           141:  * Initialize (and verify) the grammar table.
        !           142:  */
        !           143: 
        !           144: Visible Procedure
        !           145: initgram()
        !           146: {
        !           147:        register int sym;
        !           148:        register int nch;
        !           149:        register struct classinfo **cp;
        !           150:        register struct classinfo *sp;
        !           151:        node ch[MAXCHILD];
        !           152: 
        !           153: #ifndef NDEBUG
        !           154:        if (dflag)
        !           155:                fprintf(stderr, "*** initgram();\n\r");
        !           156: #endif NDEBUG
        !           157:        /* Set the node pointers in the table and check the representations.
        !           158:           The code assumes Optional and Hole are the last
        !           159:           symbols in the table, i.e. the first processed by the loop. */
        !           160: 
        !           161:        for (sym = TABLEN-1; sym >= 0; --sym) {
        !           162:                if (table[sym].r_symbol != sym) {
        !           163:                        if (sym != Hole && sym != Optional && table[sym].r_symbol == 0)
        !           164:                                continue; /* Disabled table entry */
        !           165:                        syserr("initgram: table order (%s=%d, should be %d)",
        !           166:                                table[sym].r_name, table[sym].r_symbol, sym);
        !           167:                }
        !           168:                cp = table[sym].r_class;
        !           169:                for (nch = 0; nch < MAXCHILD && (sp = cp[nch]); ++nch)
        !           170:                        ch[nch] =
        !           171:                                table[sp->c_class[0] == Optional ?
        !           172:                                        Optional : Hole].r_node;
        !           173:                table[sym].r_node = newnode(nch, sym, ch);
        !           174:                fix((value) table[sym].r_node);
        !           175:        }
        !           176: 
        !           177:        initcodes();
        !           178: #ifdef USERSUGG
        !           179:        initclasses();
        !           180: #endif USERSUGG
        !           181: }
        !           182: 
        !           183: 
        !           184: #ifdef USERSUGG
        !           185: 
        !           186: /*
        !           187:  * Add built-in commands to the suggestion tables.
        !           188:  */
        !           189: 
        !           190: Hidden Procedure
        !           191: initclasses()
        !           192: {
        !           193:        register int i;
        !           194:        register int j;
        !           195:        register struct table *tp;
        !           196: 
        !           197:        for (i = 0; i < TABLEN; ++i) {
        !           198:                tp = &table[i];
        !           199:                if (tp->r_symbol != i || i == Suggestion)
        !           200:                        continue; /* Dead entry */
        !           201:                for (j = 0; j < MAXCHILD && tp->r_class[j]; ++j) {
        !           202:                        if (isinclass(Suggestion, tp->r_class[j]))
        !           203:                                makesugg(tp->r_class[j]->c_class);
        !           204:                }
        !           205:        }
        !           206: }
        !           207: 
        !           208: 
        !           209: /*
        !           210:  * Extract suggestions from class list.
        !           211:  */
        !           212: 
        !           213: Hidden Procedure
        !           214: makesugg(cp)
        !           215:        classptr cp;
        !           216: {
        !           217:        struct table *tp;
        !           218:        string *rp;
        !           219:        char buffer[1000];
        !           220:        string bp;
        !           221:        string sp;
        !           222:        int i;
        !           223:        int nch;
        !           224: 
        !           225:        for (; *cp; ++cp) {
        !           226:                if (*cp >= TABLEN || *cp < 0)
        !           227:                        continue;
        !           228:                tp = &table[*cp];
        !           229:                rp = tp->r_repr;
        !           230:                if (rp[0] && isupper(rp[0][0])) {
        !           231:                        bp = buffer;
        !           232:                        nch = nchildren(tp->r_node);
        !           233:                        for (i = 0; i <= nch; ++i) {
        !           234:                                if (rp[i]) {
        !           235:                                        for (sp = rp[i]; *sp >= ' '; ++sp)
        !           236:                                                *bp++ = *sp;
        !           237:                                }
        !           238:                                if (i < nch && !isinclass(Optional, tp->r_class[i]))
        !           239:                                        *bp++ = '?';
        !           240:                        }
        !           241:                        if (bp > buffer) {
        !           242:                                *bp = 0;
        !           243:                                addsugg(buffer, Yes);
        !           244:                        }
        !           245:                }
        !           246:        }
        !           247: }
        !           248: 
        !           249: #endif USERSUGG
        !           250: 
        !           251: 
        !           252: /*
        !           253:  * Compaction scheme for characters to save space in grammar tables
        !           254:  * by combining characters with similar properties (digits, l.c. letters).
        !           255:  */
        !           256: 
        !           257: #define RANGE 128 /* ASCII characters are in {0 .. RANGE-1} */
        !           258: 
        !           259: Visible char code_array[RANGE];
        !           260: Visible char invcode_array[RANGE];
        !           261: Visible int lastcode;
        !           262: 
        !           263: Hidden Procedure
        !           264: initcodes()
        !           265: {
        !           266:        register int c;
        !           267: 
        !           268:        code_array['\n'] = ++lastcode;
        !           269:        invcode_array[lastcode] = '\n';
        !           270:        for (c = ' '; c <= '0'; ++c) {
        !           271:                code_array[c] = ++lastcode;
        !           272:                invcode_array[lastcode] = c;
        !           273:        }
        !           274:        for (; c <= '9'; ++c)
        !           275:                code_array[c] = lastcode;
        !           276:        for (; c <= 'a'; ++c) {
        !           277:                code_array[c] = ++lastcode;
        !           278:                invcode_array[lastcode] = c;
        !           279:        }
        !           280:        for (; c <= 'z'; ++c)
        !           281:                code_array[c] = lastcode;
        !           282:        for (; c < RANGE; ++c) {
        !           283:                code_array[c] = ++lastcode;
        !           284:                invcode_array[lastcode] = c;
        !           285:        }
        !           286: }
        !           287: 
        !           288: 
        !           289: /*
        !           290:  * Set the root of the grammar to the given symbol.  It must exist.
        !           291:  */
        !           292: 
        !           293: Visible Procedure
        !           294: setroot(name)
        !           295:        string name;
        !           296: {
        !           297:        register int k;
        !           298:        register int i;
        !           299: 
        !           300:        for (k = 1; k < TABLEN; ++k) {
        !           301:                if (table[k].r_name && Strequ(name, table[k].r_name)) {
        !           302:                        table[Rootsymbol].r_symbol = table[k].r_symbol;
        !           303:                        table[Rootsymbol].r_name = table[k].r_name;
        !           304:                        for (i = 0; i < MAXCHILD; ++i) {
        !           305:                                table[Rootsymbol].r_repr[i] = table[k].r_repr[i];
        !           306:                                table[Rootsymbol].r_class[i] = table[k].r_class[i];
        !           307:                        }
        !           308:                        table[Rootsymbol].r_repr[i] = table[k].r_repr[i];
        !           309:                        table[Rootsymbol].r_node = table[k].r_node;
        !           310:                        table[Rootsymbol].r_symbol = Rootsymbol;
        !           311:                        return;
        !           312:                }
        !           313:        }
        !           314:        syserr("Can't set root of grammar to <%s>", name);
        !           315: }
        !           316: 
        !           317: 
        !           318: /*
        !           319:  * The remainder of this file is specific for the currently used grammar.
        !           320:  */
        !           321: 
        !           322: 
        !           323: #include "boot.h" /* Has static data, so should be included only once! */
        !           324: #include "syms.h"
        !           325: 
        !           326: Visible struct table *table = b_grammar;
        !           327: 
        !           328: 
        !           329: /*
        !           330:  * Table indicating which symbols are used to form lists of items.
        !           331:  * Consulted via predicate 'issublist' in "gram.c".
        !           332:  */
        !           333: 
        !           334: Hidden classelem Asublists[] = {
        !           335:        E_plus, F_e_plus, 
        !           336:        And, And_kw, Or, Or_kw,
        !           337:        0,
        !           338: };
        !           339: 
        !           340: Hidden struct classinfo sublists[] = {Asublists};
        !           341: 
        !           342: 
        !           343: /*
        !           344:  * Predicate telling whether two symbols can form lists together.
        !           345:  * This is important for list whose elements must alternate in some
        !           346:  * way, as is the case for [KEYWORD [expression] ]*.
        !           347:  *
        !           348:  * This code must be in this file, otherwise the names and values
        !           349:  * of the symbols would have to be made public.
        !           350:  */
        !           351: 
        !           352: Visible bool
        !           353: samelevel(sym, sym1)
        !           354:        register int sym;
        !           355:        register int sym1;
        !           356: {
        !           357:        register int zzz;
        !           358: 
        !           359:        if (sym1 == sym)
        !           360:                return Yes;
        !           361:        if (sym1 < sym)
        !           362:                zzz = sym, sym = sym1, sym1 = zzz; /* Ensure sym <= sym1 */
        !           363:        /* Now always sym < sym1 */
        !           364:        return sym == Kw_plus && sym1 == E_plus
        !           365:                || sym == F_kw_plus && sym1 == F_e_plus
        !           366:                || sym == And && sym1 == And_kw
        !           367:                || sym == Or && sym1 == Or_kw;
        !           368: }
        !           369: 
        !           370: 
        !           371: /*
        !           372:  * Predicate to tell whether a symbol can form chained lists.
        !           373:  * By definition, all right-recursive symbols can do so;
        !           374:  * in addition, those listed in the class 'sublists' can do
        !           375:  * it, too (this is used for lists formed of alternating members
        !           376:  * such as KW expr KW ...).
        !           377:  */
        !           378: 
        !           379: Visible bool
        !           380: issublist(sym)
        !           381:        register int sym;
        !           382: {
        !           383:        register int i;
        !           384:        register string repr;
        !           385: 
        !           386:        Assert(sym < TABLEN);
        !           387:        if (isinclass(sym, sublists))
        !           388:                return Yes;
        !           389:        repr = table[sym].r_repr[0];
        !           390:        if (Fw_positive(repr))
        !           391:                return No;
        !           392:        for (i = 0; i < MAXCHILD && table[sym].r_class[i]; ++i)
        !           393:                ;
        !           394:        if (i <= 0)
        !           395:                return No;
        !           396:        repr = table[sym].r_repr[i];
        !           397:        if (!Fw_zero(repr))
        !           398:                return No;
        !           399:        return isinclass(sym, table[sym].r_class[i-1]);
        !           400: }

unix.superglobalmegacorp.com

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