home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1978 Charles H. Forsyth
- *
- * Modified 02-Dec-80 Bob Denny -- Conditionalize debug code for smaller size
- * Also note other mods. Now minimization is turned on at run time by '-m'.
- * More 19-Mar-82 Bob Denny -- New C library & compiler
- * This routine is unimplemented. Define MIN to turn it on. Have fun.
- */
-
- /*
- * lex -- dfa minimisation routines
- */
-
- #include <stdio.h>
- #include "lexlex.h"
-
- #ifdef MIN
- #else
- /*
- * Dummy routine
- */
- void dfamin(void)
- {
- }
- #endif
-
- #ifdef MIN
-
- member(e, v, i)
- register e, *v, i;
- {
-
- while (i--)
- if (e==*v++)
- return(1);
- return(0);
- }
-
- extern struct set **oldpart;
- extern int **newpart;
- extern int nold, nnew;
-
- struct xlist {
- struct set *x_set;
- struct trans *x_trans;
- };
-
- xcomp(a, b)
- struct xlist *a, *b;
- {
- if (a->x_trans > b->x_trans)
- return(1);
- if (a->x_trans==b->x_trans)
- return(0);
- return(-1);
- }
-
- void dfamin(void)
- {
- struct xlist *temp, *tp, *xp, *zp;
- struct trans *trp;
- int *tp2, *ip;
- struct set *gp, **xch;
- int i, j, k, niter;
-
- if(mflag == 0) return; /*** NOTE ***/
-
- #ifdef DEBUG
- fprintf(lexlog, "\nDFA minimisation (%d states)\n", ndfa);
- #endif
-
- temp = lalloc(ndfa, sizeof(*temp), "minimisation");
- oldpart = lalloc(ndfa, sizeof(*oldpart), "minimisation");
- newpart = lalloc(ndfa*2+1, sizeof(*newpart), "minimisation");
- setlist = 0;
- /*
- * partition first into final
- * states which identify different
- * translations, and non-final
- * states.
- */
- tp = temp;
- for (i = 0; i < ndfa; i++, tp++) {
- tp->x_set = dfa[i].df_name;
- if (tp->x_set->s_final)
- tp->x_trans = nfa[tp->x_set->s_final].n_trans; else
- tp->x_trans = 0;
- }
- qsort(temp, tp-temp, sizeof(*tp), xcomp);
- for (xp = temp; xp < tp; xp = zp) {
- ip = newpart;
- for (zp = xp; zp < tp && zp->x_trans==xp->x_trans; zp++)
- *ip++ = zp->x_set->s_state-dfa;
- oldpart[nold++] = newset(newpart, ip-newpart, 0);
- }
- free(temp);
- /*
- * create a new partition,
- * by considering each group in
- * the old partition. For each
- * such group, create new subgroups
- * such that two states are in the
- * same subgroup iff they have
- * transitions on the same set of
- * characters into the same
- * set of groups in the old partition.
- * repeat this process until
- * a fixed point is reached.
- */
- niter = 0;
- do {
- niter++;
-
- #ifdef DEBUG
- fprintf(lexlog, "\n%d groups in partition %d\n", nold, niter);
- #endif
-
- for (i = 0; i < nold; i++) {
- fprintf(lexlog, "group %d: ", i);
- pset(oldpart[i], 0);
- fprintf(lexlog, "\n");
- }
- nnew = 0;
- tp2 = newpart;
- for (i = 0; i < nold; i++) {
- gp = oldpart[i];
- for (j = 0; j < gp->s_len; j++) {
- if (member(gp->s_els[j], newpart, tp2-newpart))
- continue;
- *tp2++ = gp->s_els[j];
- for (k = 0; k < gp->s_len; k++)
- if (k!=j &&
- !member(gp->s_els[k], newpart,
- tp2-newpart) &&
- eqstate(gp->s_els[j],gp->s_els[k]))
- *tp2++ = gp->s_els[k];
- *tp2++ = -1;
- }
- }
- *tp2++ = -1;
- for (tp2 = newpart; *tp2 != -1; tp2 = ++ip) {
- for (ip = tp2; *ip != -1; ip++)
- ;
- oldpart[nnew++] = newset(tp2, ip-tp2, 0);
- }
- i = nold; nold = nnew; nnew = i;
- } while (nnew!=nold);
-
- #ifdef DEBUG
- if (ndfa==nnew)
- fprintf(lexlog, "\nno states saved by minimisation\n"); else
- fprintf(lexlog, "\n%d states saved by minimisation\n", ndfa-nnew);
- #endif
-
- free(newpart);
- free(oldpart);
- }
-
- eqstate(a, b)
- {
- register struct move *dp1, *dp2;
-
- /** dfa vector has no element 'df_moves', transition entries have no elements
- df_char nor df_set. Obviously unimplemented stuff.
-
- dp1 = dfa[a].df_moves;
- dp2 = dfa[b].df_moves;
- for (; dp1->df_set; dp1++, dp2++)
- if (dp2->df_set==0)
- return(0);
- else if (dp1->df_char != dp2->df_char ||
- dp1->df_set->s_group != dp2->df_set->s_group)
- return(0);
- return(dp2->df_set==0);
- **/
-
- }
- #endif
-