Annotation of researchv10no/cmd/twig/walker.c1, revision 1.1

1.1     ! root        1: /*
        !             2:  * The machine is laid out as a sequence of integers in the walker.
        !             3:  * The form described above is only used inside the preprocessor.
        !             4:  * Each machine state is one of the following sequence:
        !             5:  *
        !             6:  * TABLE <value_1><index_1>...<value_n><index_n> -1 [FAIL <fail_index>] -1
        !             7:  * or
        !             8:  * TABLE2 <value_1><index_1>...<value_n><index_n> -1 [FAIL <fail_index>] -1
        !             9:  * or
        !            10:  * ACCEPT <accept table index> -1
        !            11:  *
        !            12:  * The accept table is in the form:
        !            13:  *
        !            14:  * <tree index_1> ...<tree_index_m> -1
        !            15:  *
        !            16:  */
        !            17: /* Keutzer - all "short int"'s have been changed to "short" for
        !            18:    portability to UTS. */
        !            19: #include "symbols.h"
        !            20: /* Keutzer  1/88- _mtG now uses varargs for portability to SUN4 etc.*/
        !            21: #include <varargs.h>
        !            22: 
        !            23: #ifndef FILE
        !            24: #include <stdio.h>
        !            25: #endif
        !            26: #include <assert.h>
        !            27: 
        !            28: /* These constants must be the same as the ones in machine.c */
        !            29: #define FASTLIM        0
        !            30: #define TABLE  1
        !            31: #define FAIL   2
        !            32: #define ACCEPT 3
        !            33: #define TABLE2 4
        !            34: #define EOT    -1
        !            35: 
        !            36: /* special machine state */
        !            37: #define HANG   -1
        !            38: 
        !            39: /* used by the evaluator to interpret path table */
        !            40: #define        eSTOP   0
        !            41: #define        ePOP    -1
        !            42: #define eEVAL  -2
        !            43: #define eNEXT  -3
        !            44: #define ePUSH  -4
        !            45: 
        !            46: /* Tags that indicate the type of a value */
        !            47: #define M_BRANCH 010000
        !            48: #define M_NODE 0
        !            49: #define M_LABEL 01000
        !            50: #define MAX_NODE_VALUE 00777
        !            51: #define MTAG_SHIFT 9
        !            52: #define M_DETAG(x)     ((x)&~(M_BRANCH|M_LABEL|M_NODE))
        !            53: 
        !            54: /* predicates to tell whether a value x is of type NODE, BRANCH, or LABEL */
        !            55: #define MI_NODE(x)     (((x)&(M_BRANCH|M_LABEL))==0)
        !            56: #define MI_DEFINED(x)  ((x)!=-1)
        !            57: #define MI_LABEL(x)    (((x)&M_LABEL)!=0)
        !            58: #define MI_BRANCH(x)   (((x)&M_BRANCH)!=0)
        !            59: 
        !            60: /* build a tagged value */
        !            61: #define MV_NODE(x)     (x)
        !            62: #define MV_BRANCH(x)   ((x)|M_BRANCH)
        !            63: #define MV_LABEL(x)    ((x)|M_LABEL)
        !            64: 
        !            65: /* limits */
        !            66: /*
        !            67:  * The depth of a pattern must be 7 or less.  Otherwise the type of he
        !            68:  * partial mask in skeleton must be changed
        !            69:  */
        !            70: #define MAXDEPTH       7
        !            71: 
        !            72: /* modes */
        !            73: #define xTOPDOWN       3
        !            74: #define xABORT         2
        !            75: #define xREWRITE       1
        !            76: #define xDEFER         0
        !            77: 
        !            78: /* macros */
        !            79: #define tDO(m) _do((m)->skel, (m), 1)
        !            80: #define REWRITE        return(_m->cost = cost, xREWRITE)
        !            81: #define TOPDOWN return(_m->cost = cost, xTOPDOWN)
        !            82: #define ABORT return(xABORT)
        !            83: 
        !            84: /*
        !            85:  * REORDER macro allows a knowledgeable user to change the order
        !            86:  * of evaluation of the leaves.
        !            87:  */
        !            88: #ifndef REORDER
        !            89: #define REORDER(list)  _evalleaves(list)
        !            90: #endif
        !            91: #define EVAL   REORDER(_ll)
        !            92: 
        !            93: #define mpush(s,m)     (m)->next = s, s = m
        !            94: 
        !            95: /* skeleton structure */
        !            96: typedef struct skeleton skeleton;
        !            97: typedef struct __match __match;
        !            98: typedef struct __partial __partial;
        !            99: typedef struct __hshcls        __hshcls;       /* a hashed closure entry */
        !           100: typedef int labelset;                  /* a bit vector of labels */
        !           101: 
        !           102: struct __partial {
        !           103:        unsigned char treeno;
        !           104:        char bits;
        !           105: };
        !           106: 
        !           107: struct __hshcls {
        !           108:        __hshcls *next;
        !           109:        labelset labels;
        !           110:        int treecnt;            /* number of partial matches */
        !           111:        __partial partial[MAXTREES];
        !           112: };
        !           113: 
        !           114: struct skeleton {
        !           115:        skeleton *sibling;
        !           116:        skeleton *leftchild;            /* leftmost child */
        !           117:        skeleton *rightchild;           /* rightmost child */
        !           118:        NODEPTR root;
        !           119:        NODEPTR parent;                 /* our parent */
        !           120:        int nson;
        !           121:        int treecnt;
        !           122:        __match *succ[MAXLABELS];
        !           123:        __partial *partial;
        !           124:        __match *winner;
        !           125:        COST mincost;
        !           126: };
        !           127: 
        !           128: struct __match {
        !           129:        __match **lleaves;      /* labelled leaves */
        !           130:        skeleton *skel;         /* back pointer to associated skeleton node */
        !           131:        COST cost;
        !           132:        short tree;
        !           133:        short mode;
        !           134: };
        !           135: 
        !           136: struct freeb {
        !           137:        struct freeb *next;
        !           138: };
        !           139: 
        !           140: struct _mem {
        !           141:         struct _mem *next;
        !           142:         int size;       /* size of individual elements in bytes */
        !           143:         int blkf;       /* blocking factor */
        !           144:         int bsize;      /* block size */
        !           145:         char *block;    /* block */
        !           146:         int cnt;        /* count of free elem in block */
        !           147:         char *freelist; /* free list */
        !           148:         int totelem;    /* total number elements we have */
        !           149:         int freecnt;    /* number of times mem_free was called */
        !           150: };
        !           151: 
        !           152: /* turn this flag on if your machine has a fast byte string zero operation */
        !           153: /*#define BZERO        1*/
        !           154: int mtDebug = 0;
        !           155: int treedebug = 0;
        !           156: extern int _machstep();
        !           157: extern short mtStart;
        !           158: extern short mtTable[], mtAccept[], mtMap[], mtPaths[], mtPathStart[];
        !           159: #ifdef LINE_XREF
        !           160:        extern short mtLine[];
        !           161: #endif
        !           162: 
        !           163: #ifndef MPBSIZE
        !           164: #define MPBSIZE 8000
        !           165: #endif
        !           166: 
        !           167: #ifdef ADDCOST
        !           168: #define DEFAULT_COST sumleaves(_ll)
        !           169: COST sumleaves(list) __match **list;
        !           170: {COST cost;
        !           171:  cost=ZEROCOST;
        !           172:  for(; *list; list++)
        !           173:    {ADDCOST((cost),(*list)->cost);
        !           174:    }
        !           175:  return cost;
        !           176: }
        !           177: #endif
        !           178: 
        !           179: extern NODEPTR mtGetNodes(), mtAction();
        !           180: extern skeleton *_allocskel();
        !           181: extern __match *_allocmatch();
        !           182: extern __partial *_allocpartial();
        !           183: 
        !           184: __match *_mpblock[MPBSIZE], **_mpbtop;
        !           185: 
        !           186: __match **
        !           187: _getleaves (mp, skp)
        !           188:        register __match *mp; register skeleton *skp;
        !           189: {
        !           190:        skeleton *stack[MAXDEPTH];
        !           191:        skeleton **stp = stack;
        !           192:        register short *sip = &mtPaths[mtPathStart[mp->tree]];
        !           193:        register __match **mmp = _mpbtop;
        !           194:        __match **mmp2 = mmp;
        !           195:        if((_mpbtop += *sip++ + 1) > &_mpblock[MPBSIZE]) {
        !           196:                printf("Tree too large: make MPBSIZE larger.\n\
        !           197: (i.e. cc -c -DMPBSIZE=%d walker.c)\n",MPBSIZE*2);
        !           198:                assert(0);
        !           199:        }
        !           200: 
        !           201:        for(;;)
        !           202:                switch(*sip++) {
        !           203:                case ePUSH:
        !           204:                        *stp++ = skp;
        !           205:                        skp = skp->leftchild;
        !           206:                        break;
        !           207: 
        !           208:                case eNEXT:
        !           209:                        skp = skp->sibling;
        !           210:                        break;
        !           211: 
        !           212:                case eEVAL:
        !           213:                        if ((mp = skp->succ[M_DETAG(*sip++)])==NULL) abort();
        !           214:                        *mmp++ = mp;
        !           215:                        break;
        !           216: 
        !           217:                case ePOP:
        !           218:                        skp = *--stp;
        !           219:                        break;
        !           220: 
        !           221:                case eSTOP:
        !           222:                        *mmp = NULL;
        !           223:                        return (mmp2);
        !           224:                }
        !           225: }
        !           226: 
        !           227: _evalleaves (mpp)
        !           228:        register __match **mpp;
        !           229: {
        !           230:        for (; *mpp!=NULL; mpp++) {
        !           231:                register __match *mp = *mpp;
        !           232:                _do (mp->skel, mp, 1);
        !           233:        }
        !           234: }
        !           235: 
        !           236: 
        !           237: _do(sp, winner, evalall)
        !           238:        skeleton *sp; register __match *winner; int evalall;
        !           239: {
        !           240:        register __match **mpp;
        !           241:        register skeleton *skel = winner->skel;
        !           242:        if(winner==NULL) {
        !           243:                _nowin(sp);
        !           244:                return;
        !           245:        }
        !           246:        if(winner->mode==xDEFER || (evalall && winner->mode!=xTOPDOWN))
        !           247:                REORDER(winner->lleaves);
        !           248:        mtSetNodes (skel->parent, skel->nson,
        !           249:                skel->root=mtAction (winner->tree, winner->lleaves, sp));
        !           250: }
        !           251: 
        !           252: skeleton *
        !           253: _walk(sp, ostate)
        !           254:        register skeleton *sp;
        !           255:        int ostate;
        !           256: {
        !           257:        int state, nstate, nson;
        !           258:        register __partial *pp;
        !           259:        register __match *mp, *mp2;
        !           260:        register skeleton *nsp, *lastchild = NULL;
        !           261:        NODEPTR son, root;
        !           262: 
        !           263:        root = sp->root;
        !           264:        nson = 1; sp->mincost = INFINITY;
        !           265:        state = _machstep (ostate, root, mtValue(root));
        !           266: 
        !           267:        while((son = mtGetNodes(root, nson))!=NULL) {
        !           268:                nstate = _machstep (state, NULL, MV_BRANCH(nson));
        !           269:                nsp = _allocskel();
        !           270:                nsp->root = son;
        !           271:                nsp->parent = root;
        !           272:                nsp->nson = nson;
        !           273:                _walk(nsp, nstate);
        !           274:                if(COSTLESS(nsp->mincost,INFINITY)) {
        !           275:                        assert (nsp->winner->mode==xREWRITE);
        !           276:                        _do(nsp, nsp->winner, 0);
        !           277:                        _freeskel(nsp);
        !           278:                        continue;
        !           279:                }
        !           280:                _merge (sp, nsp);
        !           281:                if (lastchild==NULL) sp->leftchild = nsp;
        !           282:                else lastchild->sibling = nsp;
        !           283:                lastchild = nsp;
        !           284:                nson++;
        !           285:        }
        !           286: 
        !           287:        for (pp = sp->partial; pp < &sp->partial[sp->treecnt]; pp++)
        !           288:                if (pp->bits&01==1) {
        !           289:                        mp = _allocmatch();
        !           290:                        mp->tree = pp->treeno;
        !           291:                        _addmatches (ostate, sp, mp);
        !           292:                }
        !           293:        if(son==NULL && nson==1)
        !           294:                _closure (state, ostate, sp);
        !           295: 
        !           296:        sp->rightchild = lastchild;
        !           297:        if (root==NULL) {
        !           298:                COST c; __match *win; int i; nsp = sp->leftchild;
        !           299:                c = INFINITY;
        !           300:                win = NULL;
        !           301:                for (i = 0; i < MAXLABELS; i++) {
        !           302:                        mp = nsp->succ[i];
        !           303:                        if (mp!=NULL && COSTLESS (mp->cost, c))
        !           304:                                { c = mp->cost; win = mp; }
        !           305:                }
        !           306:                _do (nsp, win, 0);
        !           307:        }
        !           308:        return(sp);
        !           309: }
        !           310: 
        !           311: /*
        !           312:  * Convert the start state which has a large branching factor into
        !           313:  * a index table.  This must be called before the matcher is used.
        !           314:  */
        !           315: static short _nodetab[MAXNDVAL], _labeltab[MAXLABELS];
        !           316: _matchinit()
        !           317: {
        !           318:        short *sp;
        !           319: /* Keutzer - this syntax doesn't work on UTS
        !           320:        struct pair { short val, where } *pp; 
        !           321: */
        !           322:        struct pair { short val; short where; } *pp; 
        !           323:        for (sp=_nodetab; sp < &_nodetab[MAXNDVAL]; sp++) *sp = HANG;
        !           324:        for (sp=_labeltab; sp < &_labeltab[MAXLABELS]; sp++) *sp = HANG;
        !           325:        sp = &mtTable[mtStart];
        !           326:        assert (*sp==TABLE);
        !           327:        for (pp = (struct pair *) ++sp; pp->val!=EOF; pp++) {
        !           328:                if (MI_NODE(pp->val))
        !           329:                        _nodetab[M_DETAG(pp->val)] = pp->where;
        !           330:                else if (MI_LABEL(pp->val))
        !           331:                        _labeltab[M_DETAG(pp->val)] = pp->where;
        !           332:        }
        !           333: }
        !           334: 
        !           335: int
        !           336: _machstep(state, root, input)
        !           337:        short state, input;
        !           338:        NODEPTR root;
        !           339: {
        !           340:        register short *stp = &mtTable[state];
        !           341:        int start = 0;
        !           342:        if (state==HANG)
        !           343:                return (input==(MV_BRANCH(1)) ? mtStart : HANG);
        !           344: rescan:
        !           345:        if (stp==&mtTable[mtStart]) {
        !           346:                if (MI_NODE(input)) return(_nodetab[M_DETAG(input)]);
        !           347:                if (MI_LABEL(input)) return(_labeltab[M_DETAG(input)]);
        !           348:        }
        !           349:        
        !           350:        for(;;) {
        !           351:                if(*stp==ACCEPT) stp += 2;
        !           352: 
        !           353:                if(*stp==TABLE) {
        !           354:                        stp++;
        !           355:                        while(*stp!=EOT) {
        !           356:                                if(input==*stp) {
        !           357:                                        return(*++stp);
        !           358:                                }
        !           359:                                stp += 2;
        !           360:                        }
        !           361:                        stp++;
        !           362:                }
        !           363:                if(*stp!=FAIL) {
        !           364:                        if (start) return (HANG);
        !           365:                        else { stp = &mtTable[mtStart]; start = 1;  goto rescan;}
        !           366:                } else {
        !           367:                        stp++;
        !           368:                        stp = &mtTable[*stp];
        !           369:                        goto rescan;
        !           370:                }
        !           371:        }
        !           372: }
        !           373: 
        !           374: _addmatches(ostate, sp, np)
        !           375:        int ostate;
        !           376:        register skeleton *sp;
        !           377:        register __match *np;
        !           378: {
        !           379:        int label;
        !           380:        int state;
        !           381:        register __match *mp;
        !           382: 
        !           383:         label = mtMap[np->tree];
        !           384: 
        !           385:        /*
        !           386:         * this is a very poor substitute for good design of the DFA.
        !           387:         * What we need is a special case that allows any label to be accepted
        !           388:         * by the start state but we don't want the start state to recognize
        !           389:         * them after a failure.
        !           390:         */
        !           391:        state = _machstep(ostate, NULL, MV_LABEL(label));
        !           392:        if (ostate!=mtStart  && state==HANG) {
        !           393:                _freematch(np);
        !           394:                return;
        !           395:        }
        !           396: 
        !           397:        np->lleaves = _getleaves (np, sp);
        !           398:        np->skel = sp;
        !           399:         if((np->mode = mtEvalCost(np, np->lleaves, sp))==xABORT)
        !           400:        {
        !           401:                _freematch(np);
        !           402:                return;
        !           403:        }
        !           404: 
        !           405: /*
        !           406:        if(np->mode==xREWRITE && COSTLESS(np->cost, sp->mincost)) {
        !           407:                sp->mincost = np->cost;
        !           408:                sp->winner = np;
        !           409:        }
        !           410: */
        !           411:        if ((mp = sp->succ[label])!=NULL) {
        !           412:                if (!COSTLESS (np->cost, mp->cost))
        !           413:                        { _freematch(np); return; }
        !           414:                else _freematch(mp);
        !           415:        }
        !           416:        if(COSTLESS(np->cost,sp->mincost)) {
        !           417:                if(np->mode==xREWRITE) {
        !           418:                        sp->mincost = np->cost; sp->winner = np; }
        !           419:                else { sp->mincost = INFINITY; sp->winner = NULL; }
        !           420:        }
        !           421:        sp->succ[label] = np;
        !           422:        _closure(state, ostate, sp);
        !           423: }
        !           424: 
        !           425: _closure(state, ostate, skp)
        !           426:        int state, ostate;
        !           427:        skeleton *skp;
        !           428: {
        !           429:        register struct ap { short tree, depth; } *ap;
        !           430:        short *sp = &mtTable[state];
        !           431:        register __match *mp;
        !           432: 
        !           433:        if(state==HANG || *sp!=ACCEPT) return(NULL);
        !           434: 
        !           435:        for(ap = (struct ap *) &mtAccept[*++sp]; ap->tree!=-1; ap++)
        !           436:                if (ap->depth==0) {
        !           437:                        mp = _allocmatch();     
        !           438:                        mp->tree = ap->tree;
        !           439:                        _addmatches (ostate, skp, mp);
        !           440:                } else {
        !           441:                        register __partial *pp, *lim = &skp->partial[skp->treecnt];
        !           442:                        for(pp=skp->partial; pp < lim; pp++)
        !           443:                                if(pp->treeno==ap->tree)
        !           444:                                        break;
        !           445:                        if(pp==lim) {
        !           446:                                skp->treecnt++;
        !           447:                                pp->treeno = ap->tree;
        !           448:                                pp->bits = (1<<(ap->depth));
        !           449:                        } else pp->bits |= (1<<(ap->depth));
        !           450:                }
        !           451: }
        !           452: 
        !           453: _merge (old, new)
        !           454:        skeleton *old, *new;
        !           455: {
        !           456:        register __partial *op = old->partial, *np = new->partial;
        !           457:        int nson = new->nson;
        !           458:        register __partial *lim = np + new->treecnt;
        !           459:        if (nson==1) {
        !           460:                old->treecnt = new->treecnt;
        !           461:                for(; np < lim; op++, np++) {
        !           462:                        op->treeno = np->treeno;
        !           463:                        op->bits = np->bits/2;
        !           464:                }
        !           465:        } else {
        !           466:                __partial *newer = _allocpartial();
        !           467:                register __partial *newerp = newer;
        !           468:                register int cnt;
        !           469:                lim = op+old->treecnt;
        !           470:                for(cnt=new->treecnt; cnt-- ; np++) {
        !           471:                        for(op = old->partial; op < lim; op++)
        !           472:                                if (op->treeno == np->treeno) {
        !           473:                                        newerp->treeno = op->treeno;
        !           474:                                        newerp++->bits = op->bits & (np->bits/2);
        !           475:                                        break;
        !           476:                                }
        !           477:                }
        !           478:                _freepartial(old->partial);
        !           479:                old->partial = newer;
        !           480:                old->treecnt = newerp-newer;
        !           481:        }
        !           482: }
        !           483:  
        !           484: /* Save and Allocate Matches */
        !           485: #define BLKF   100
        !           486: __match *freep = NULL;
        !           487: static int _count = 0;
        !           488: static __match *_blockp = NULL;
        !           489: #ifdef CHECKMEM
        !           490: int x_matches, f_matches;
        !           491: #endif
        !           492: 
        !           493: __match *
        !           494: _allocmatch()
        !           495: {
        !           496:        __match *mp;
        !           497: 
        !           498:        if(freep!=NULL) {
        !           499:                mp = freep;
        !           500:                freep = ((__match *)((struct freeb *) freep)->next);
        !           501: #ifdef CHECKMEM
        !           502:                f_matches--;
        !           503: #endif
        !           504:        } else {
        !           505:                if(_count==0) {
        !           506:                        _blockp = (__match *) malloc (BLKF*sizeof (__match));
        !           507:                        _count = BLKF;
        !           508: #ifdef CHECKMEM
        !           509:                        x_matches += BLKF;
        !           510: #endif
        !           511:                }
        !           512:                mp = _blockp++;
        !           513:                _count--;
        !           514:        }
        !           515:        return(mp);
        !           516: }
        !           517: 
        !           518: _freematch(mp)
        !           519:        __match *mp;
        !           520: {
        !           521:        ((struct freeb *) mp)->next = (struct freeb *) freep;
        !           522:        freep = mp;
        !           523: #ifdef CHECKMEM
        !           524:        f_matches++;
        !           525: #endif
        !           526: }
        !           527: 
        !           528: static __partial *pfreep = NULL;
        !           529: static int pcount = 0;
        !           530: static __partial *pblock = NULL;
        !           531: #ifdef CHECKMEM
        !           532: static int x_partials, f_partials;
        !           533: #endif
        !           534: 
        !           535: __partial *
        !           536: _allocpartial()
        !           537: {
        !           538:        __partial *pp;
        !           539:        if (pfreep!=NULL) {
        !           540:                pp = pfreep;
        !           541:                pfreep = *(__partial **) pp;
        !           542: #ifdef CHECKMEM
        !           543:                f_partials--;
        !           544: #endif
        !           545:        } else {
        !           546:                if (pcount==0) {
        !           547:                        pblock=(__partial *)malloc(BLKF*MAXTREES*sizeof(__partial));
        !           548:                        pcount = BLKF;
        !           549: #ifdef CHECKMEM
        !           550:                        x_partials += BLKF;
        !           551: #endif
        !           552:                }
        !           553:                pp = pblock;
        !           554:                pblock += MAXTREES;
        !           555:                pcount--;
        !           556:        }
        !           557:        return(pp);
        !           558: }
        !           559: 
        !           560: _freepartial(pp)
        !           561:        __partial *pp;
        !           562: {
        !           563:        * (__partial **)pp = pfreep;
        !           564:        pfreep = pp;
        !           565: #ifdef CHECKMEM
        !           566:        f_partials++;
        !           567: #endif
        !           568: }
        !           569: 
        !           570: 
        !           571: /* storage management */
        !           572: static skeleton *sfreep = NULL;
        !           573: static int scount = 0;
        !           574: static skeleton * sblock = NULL;
        !           575: 
        !           576: skeleton *
        !           577: _allocskel()
        !           578: {
        !           579:        skeleton *sp;
        !           580:        int i;
        !           581:        if(sfreep!=NULL) {
        !           582:                sp = sfreep;
        !           583:                sfreep = sp->sibling;
        !           584:        } else {
        !           585:                if(scount==0) {
        !           586:                        sblock = (skeleton *) malloc (BLKF * sizeof (skeleton));
        !           587:                        scount = BLKF;
        !           588:                }
        !           589:                sp = sblock++;
        !           590:                scount--;
        !           591:        }
        !           592:        sp->sibling = NULL; sp->leftchild = NULL;
        !           593:        for (i=0; i < MAXLABELS; sp->succ[i++] = NULL);
        !           594:        sp->treecnt = 0;
        !           595:        sp->partial = _allocpartial();
        !           596:        return(sp);
        !           597: }
        !           598: 
        !           599: _freeskel(sp)
        !           600:        skeleton *sp;
        !           601: {
        !           602:        int i;
        !           603:        __match *mp;
        !           604:        if(sp==NULL) return;
        !           605:        _freeskel (sp->leftchild);
        !           606:        _freeskel (sp->sibling);
        !           607:        _freepartial (sp->partial);
        !           608:        for (i=0; i < MAXLABELS; i++)
        !           609:                if ((mp = sp->succ[i])!=NULL) _freematch (mp);
        !           610:        sp->sibling = sfreep;
        !           611:        sfreep = sp;
        !           612: }
        !           613: 
        !           614: _match()
        !           615: {
        !           616:        skeleton *sp;
        !           617:        sp = _allocskel();
        !           618:        sp->root = NULL;
        !           619:        _mpbtop = _mpblock;
        !           620:        _freeskel(_walk(sp, HANG));
        !           621: #ifdef CHECKMEM
        !           622:        if(f_matches+_count!=x_matches) {
        !           623:                printf(";#m %d %d %d\n", f_matches, _count, x_matches);
        !           624:                assert(0);
        !           625:        }
        !           626:        if(f_partials+pcount!=x_partials) {
        !           627:                printf(";#p %d %d %d\n", f_partials, pcount, x_partials);
        !           628:                assert(0);
        !           629:        }
        !           630: #endif
        !           631: }
        !           632: 
        !           633: /* Keutzer  1/88- _mtG now uses varargs for portability to SUN4 etc.*/
        !           634: NODEPTR _mtG(va_alist)
        !           635: va_dcl
        !           636: {
        !           637:     NODEPTR root;
        !           638:     int i=0;
        !           639:     va_list p_var;
        !           640:     va_start(p_var);
        !           641:     root = va_arg(p_var,NODEPTR);
        !           642:     while( (i = va_arg(p_var,int)) != -1){
        !           643:         root = mtGetNodes(root, i);
        !           644:     }
        !           645:     va_end(p_var);
        !           646:     return(root);
        !           647: }
        !           648: 
        !           649: /* diagnostic routines */
        !           650: #ifdef NOMARK
        !           651: markIfNoMatch(skp,mark)
        !           652:        skeleton *skp;
        !           653:        int mark;
        !           654: {}
        !           655: #else
        !           656: markIfNoMatch(skp,mark) skeleton *skp; int mark;
        !           657: {skeleton *child; int i; int found=0;
        !           658:  for(i=0; i<MAXLABELS; i++)
        !           659:         if (skp->succ[i]) found=1;
        !           660:  if (!found) skp->root->mark=mark;
        !           661:  for(child=skp->leftchild; child; child=child->sibling)
        !           662:        markIfNoMatch(child,mark);
        !           663: }
        !           664: #endif
        !           665: 
        !           666: _nowin(skp) skeleton *skp;
        !           667: {
        !           668:   markIfNoMatch(skp,1);
        !           669:   printf("# No match was found for the nodes printed in lowercase\n");
        !           670:   printTree(skp->root);
        !           671:   markIfNoMatch(skp,0);
        !           672: }

unix.superglobalmegacorp.com

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