home *** CD-ROM | disk | FTP | other *** search
/ Boston 2 / boston-2.iso / DOS / PROGRAM / C / LEX / DFA.C < prev    next >
Text File  |  1993-12-01  |  5KB  |  194 lines

  1. /*
  2.  * Copyright (c) 1978 Charles H. Forsyth
  3.  *
  4.  * Modified 02-Dec-80 Bob Denny -- Conditionalize debug code for reduced size
  5.  * Modified 29-May-81 Bob Denny -- Clean up overlay stuff for RSX.
  6.  * More     19-Mar-82 Bob Denny -- New C library & compiler
  7.  * More     03-May-82 Bob Denny -- Final touches, remove unreferenced autos
  8.  * More     29-Aug-82 Bob Denny -- Clean up -d printouts
  9.  * More     29-Aug-82 Bob Denny -- Reformat for readability and comment
  10.  *                                 while learning about LEX.
  11.  * More        20-Nov-83 Scott Guthery -- Adapt for IBM PC & DeSmet C
  12.  */
  13.  
  14. /*
  15.  *    *********
  16.  *    * DFA.C *
  17.  *    *********
  18.  *
  19.  * LEX -- DFA construction routines
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include "lexlex.h"
  24.  
  25. extern struct set *eclosure();          /* Used only by DFA */
  26. extern struct dfa *defalt();            /* Used only by DFA */
  27. extern struct move *stbase();           /* Used only by DFA */
  28.  
  29. /*
  30.  * Build the DFA from the NFA
  31.  */
  32. dfabuild()
  33.    {
  34.    struct trans *trp;
  35.    struct nfa **vec, **tp, *np, *temp[MAXNFA+1];
  36.    int a, i;
  37.    struct set **sp, *stack[MAXDFA], **spp, *xp;  /* DFA set stack */
  38.    struct dfa *state;                  /* --> current DFA state */
  39.    struct xset *xs, *xse;
  40.  
  41.   /*
  42.    * Simulate an epsilon transition from nfa state 0 to
  43.    * the initial states of the machines for each
  44.    * translation.
  45.    */
  46.    nfa[0].n_char = EPSILON;            /* Set NFA state 0 transition EPSILON */
  47.    /*
  48.     * Allocate a state vector, each node of which will
  49.     * point to an NFA starting state.  Each translation
  50.     * generates an NFA, so the number of translations
  51.     * equals the number of NFA start states.
  52.     */
  53.    vec = lalloc(i = (transp-trans)+1, sizeof(*vec), "dfabuild");
  54.    /*
  55.     * Fill in the start state vector
  56.     */
  57.    vec[0] = nfa;                       /* vec[0] always --> NFA state 0 */
  58.    for (a = 1, trp = trans; trp < transp; trp++)  /* For each translation */
  59.       vec[a++] = trp->t_start;         /* Pick up the NFA start state */
  60.    /*
  61.     * Now build the set sp --> e-CLOSURE(vec)
  62.     */
  63.    sp = eclosure(newset(vec, i, 1));
  64.    free(vec);                          /* Deallocate the start state vector */
  65.  
  66.    /*
  67.     * At this point state 0 of the DFA is constructed.
  68.     * This is the start state of the DFA.
  69.     * Mark it "added" and push it on to the stack.
  70.     */
  71.    sp->s_flag |= ADDED;
  72.    spp = stack;
  73.    *spp++ = sp;
  74.    /*
  75.     * From state 0, which is now stacked, all further DFA
  76.     * states will be derived.
  77.     */
  78.    while (spp > stack)
  79.       {
  80.       sp = *--spp;
  81.       for (a = 0; a < NCHARS; a++)
  82.          insets[a] = 0;
  83.       xse = sets;
  84.       for (i = 0; i < sp->s_len; i++)
  85.          xse = addset(sp->s_els[i], xse);
  86.       state = newdfa();
  87.       sp->s_state = state;
  88.       state->df_name = sp;
  89. #ifdef DEBUG
  90.       if (lldebug)
  91.          {
  92.          fprintf(lexlog, "build state %d ", state-dfa);
  93.          pset(sp, 1);
  94.          fprintf(lexlog, "\n");
  95.          }
  96. #endif
  97.       state->df_ntrans = xse-sets;
  98.       for (xs = sets; xs < xse; xs++)
  99.          {
  100.          a = xs->x_char&0377;
  101.          tp = temp;
  102.          for (i = 0; i < sp->s_len; i++)
  103.             if ((np = sp->s_els[i])->n_char==a ||
  104.                 np->n_char==CCL &&
  105.                 np->n_ccl[a/NBPC]&(1<<(a%NBPC)))
  106.                add(temp, &tp, np->n_succ[0]);
  107.          xp = newset(temp, tp-temp, 1);
  108.          xp = eclosure(xp);
  109. #ifdef DEBUG
  110.          if (lldebug)
  111.             {
  112.             putc('\t', lexlog);
  113.             chprint(a);
  114.             putc('\t', lexlog);
  115.             pset(xp, 1);
  116.             fprintf(lexlog, "\n");
  117.             }
  118. #endif
  119.          xs->x_set = xp;
  120.          if (xp->s_state==0 && (xp->s_flag&ADDED)==0)
  121.             {
  122.             xp->s_flag |= ADDED;
  123.             if (spp >= stack+MAXDFA)
  124.                {
  125.                error("dfabuild: stack overflow");
  126.                exit(1);
  127.                }
  128.             *spp++ = xp;
  129.             }
  130.          }
  131.       state->df_default = defalt(state, &xse);
  132.       setbase(state, stbase(xse), xse);
  133.       }
  134.    }
  135.  
  136. /*
  137.  * If an nfa state is not already a member of the vector `base', add it.
  138.  */
  139. add(base, tpp, np)
  140. struct nfa ***tpp, **base, *np;
  141.    {
  142.    register struct nfa **tp;
  143.  
  144.    for (tp = base; tp < *tpp; tp++)
  145.       if (*tp == np)
  146.          return;
  147.    *(*tpp)++ = np;
  148.    }
  149.  
  150. /*
  151.  * Add the character(s) on which state `np' branches to the transition vector.
  152.  */
  153. addset(np, xse)
  154. register struct nfa *np;
  155. struct xset *xse;
  156.    {
  157.    register int a;
  158.    register char *ccl;
  159.  
  160.    if ((a = np->n_char) < NCHARS)
  161.       xse = addxset(a, xse);
  162.    if (a != CCL)
  163.       return(xse);
  164.    ccl = np->n_ccl;
  165.    for (a = 0; a < NCHARS; a++)
  166.       if (ccl[a/NBPC]&(1<<(a%NBPC)))
  167.          xse = addxset(a, xse);
  168.    return(xse);
  169.    }
  170.  
  171. /*
  172.  * Add a character to the transition vector, if it isn't there already.
  173.  */
  174. addxset(a, xse)
  175. register int a;
  176. struct xset *xse;
  177.    {
  178.    register struct xset *xs;
  179.    register int temp;
  180.    /*
  181.    * VMS native doesn't do this correctly:
  182.    *    if (insets[a]++)
  183.    */
  184.    temp = insets[a];
  185.    insets[a] += 1;
  186.    if (temp)
  187.       return(xse);
  188.    xs = xse++;
  189.    xs->x_char = a;
  190.    xs->x_set = NULL;
  191.    xs->x_defsame = 0;
  192.    return(xse);
  193.    }
  194.