# 2.11BSD#431 - /usr/src/new/PORT/B/src/bed/gram.c

##### Functions

    allowed           X
    gram              X
    initclasses       X
    initcodes         X
    initgram          X
    isinclass         X
    issublist         X
    makesugg          X
    nametosym         X
    noderepr          X
    samelevel         X
    setroot           X
    symname           X

##### Variables

    Asublists         X
    code_array        X
    invcode_array     X
    lastcode          X
    sublists          X
    table             X

##### Macros

    RANGE             X

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

#### Defined functions

allowed defined in line 126; used 6 times

- in /usr/src/new/PORT/B/src/bed/deco.c line 270, 286, 373
- in /usr/src/new/PORT/B/src/bed/que1.c line 205, 303, 480

gram defined in line 73; used 4 times

- in /usr/src/new/PORT/B/src/bed/deco.c line 410
- in /usr/src/new/PORT/B/src/bed/demo.c line 651
- in /usr/src/new/PORT/B/src/bed/edit.c line 344
- in /usr/src/new/PORT/B/src/bed/gram.h line 29

initclasses defined in line 190; used 1 times

- in line 179

initcodes defined in line 263; used 1 times

- in line 177

initgram defined in line 144; used 1 times

- in /usr/src/new/PORT/B/src/bed/main.c line 163

isinclass defined in line 25; used 12 times

- in line 34, 136, 202, 238, 387, 399
- in /usr/src/new/PORT/B/src/bed/inse.c line 41, 283
- in /usr/src/new/PORT/B/src/bed/que2.c line 620-621(2), 691, 759

issublist defined in line 379; used 7 times

- in /usr/src/new/PORT/B/src/bed/goto.c line 269
- in /usr/src/new/PORT/B/src/bed/move.c line 117
- in /usr/src/new/PORT/B/src/bed/supr.c line 126
- in /usr/src/new/PORT/B/src/bed/wide.c line 91, 123, 174, 311

makesugg defined in line 213; used 1 times

- in line 203

nametosym defined in line 105; used 1 times

- in /usr/src/new/PORT/B/src/bed/edit.c line 289

noderepr defined in line 53; used 72 times

- in /usr/src/new/PORT/B/src/bed/deco.c line 135, 183, 191, 259, 349, 480, 547, 640
- in /usr/src/new/PORT/B/src/bed/eval.c line 65, 156
- in /usr/src/new/PORT/B/src/bed/goto.c line 121, 146, 194, 242, 262, 280
- in /usr/src/new/PORT/B/src/bed/gram.h line 28
- in /usr/src/new/PORT/B/src/bed/ins2.c line 262, 309, 338
- in /usr/src/new/PORT/B/src/bed/inse.c line 155, 219
- in /usr/src/new/PORT/B/src/bed/line.c line 61(2), 79, 96, 133, 214
- in /usr/src/new/PORT/B/src/bed/move.c line 49, 256, 421, 462
- in /usr/src/new/PORT/B/src/bed/outp.c line 257, 276, 307, 323, 353, 412
- in /usr/src/new/PORT/B/src/bed/que1.c line 171, 205, 245, 343, 422, 476, 501, 549
- in /usr/src/new/PORT/B/src/bed/que2.c line 146, 196, 282, 407, 488
- in /usr/src/new/PORT/B/src/bed/save.c line 52
- in /usr/src/new/PORT/B/src/bed/scrn.c line 317
- in /usr/src/new/PORT/B/src/bed/sugg.c line 429, 436, 458
- in /usr/src/new/PORT/B/src/bed/supr.c line 27, 101, 280, 303, 382, 416, 463, 485, 598, 698, 817, 907, 963, 979, 1009
- in /usr/src/new/PORT/B/src/bed/wide.c line 179

samelevel defined in line 352; used 8 times

- in /usr/src/new/PORT/B/src/bed/deco.c line 377
- in /usr/src/new/PORT/B/src/bed/goto.c line 313
- in /usr/src/new/PORT/B/src/bed/move.c line 117, 138, 149
- in /usr/src/new/PORT/B/src/bed/wide.c line 110, 257, 316

setroot defined in line 293; used 4 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 121-125(3), 236

symname defined in line 87; used 3 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 770
- in /usr/src/new/PORT/B/src/bed/gram.h line 32
- in /usr/src/new/PORT/B/src/bed/save.c line 183

#### Defined variables

Asublists defined in line 334; used 1 times

- in line 340

code_array defined in line 259; used 7 times

- in line 268-283(6)
- in /usr/src/new/PORT/B/src/bed/tabl.h line 43

invcode_array defined in line 260; used 5 times

- in line 269-272(2), 278, 284
- in /usr/src/new/PORT/B/src/bed/tabl.h line 44

lastcode defined in line 261; used 10 times

- in line 268-284(10)

rcsid defined in line 2; never used
sublists defined in line 340; used 1 times

- in line 387

table defined in line 326; used 36 times

- in line 65, 77-78(2), 93-94(2), 113, 136, 162-174(8), 198, 228, 301-310(15), 389-399(4)

#### Defined macros

RANGE defined in line 257; used 3 times

- in line 259-260(2), 282

Last modified: 1985-08-27 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1131 |