Annotation of researchv10no/cmd/twig/examples/walker.c, revision 1.1

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

unix.superglobalmegacorp.com

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