/* cmptmps - compress template table entries * * Template tables are compressed by using the 'template equivalence * classes', which are collections of transition character equivalence * classes which always appear together in templates - really meta-equivalence * classes. */ void cmptmps(void) { int tmpstorage[CSIZE + 1]; int *tmp = tmpstorage, i, j; int totaltrans, trans; peakpairs = numtemps * numecs + tblend; if (usemecs) { /* Create equivalence classes based on data gathered on * template transitions. */ nummecs = cre8ecs(tecfwd, tecbck, numecs); } else nummecs = numecs; while (lastdfa + numtemps + 1 >= current_max_dfas) increase_max_dfas(); /* Loop through each template. */ for (i = 1; i <= numtemps; ++i) { /* Number of non-jam transitions out of this template. */ totaltrans = 0; for (j = 1; j <= numecs; ++j) { trans = tnxt[numecs * i + j]; if (usemecs) { /* The absolute value of tecbck is the * meta-equivalence class of a given * equivalence class, as set up by cre8ecs(). */ if (tecbck[j] > 0) { tmp[tecbck[j]] = trans; if (trans > 0) ++totaltrans; } } else { tmp[j] = trans; if (trans > 0) ++totaltrans; } } /* It is assumed (in a rather subtle way) in the skeleton * that if we're using meta-equivalence classes, the def[] * entry for all templates is the jam template, i.e., * templates never default to other non-jam table entries * (e.g., another template) */ /* Leave room for the jam-state after the last real state. */ mkentry(tmp, nummecs, lastdfa + i + 1, JAMSTATE, totaltrans); } }
void genctbl() { register int i; int end_of_buffer_action = num_rules + 1; /* Table of verify for transition and offset to next state. */ out_dec( "static yyconst struct yy_trans_info yy_transition[%d] =\n", tblend + numecs + 1 ); outn( " {" ); /* We want the transition to be represented as the offset to the * next state, not the actual state number, which is what it currently * is. The offset is base[nxt[i]] - (base of current state)]. That's * just the difference between the starting points of the two involved * states (to - from). * * First, though, we need to find some way to put in our end-of-buffer * flags and states. We do this by making a state with absolutely no * transitions. We put it at the end of the table. */ /* We need to have room in nxt/chk for two more slots: One for the * action and one for the end-of-buffer transition. We now *assume* * that we're guaranteed the only character we'll try to index this * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure * there's room for jam entries for other characters. */ while ( tblend + 2 >= current_max_xpairs ) expand_nxt_chk(); while ( lastdfa + 1 >= current_max_dfas ) increase_max_dfas(); base[lastdfa + 1] = tblend + 2; nxt[tblend + 1] = end_of_buffer_action; chk[tblend + 1] = numecs + 1; chk[tblend + 2] = 1; /* anything but EOB */ /* So that "make test" won't show arb. differences. */ nxt[tblend + 2] = 0; /* Make sure every state has an end-of-buffer transition and an * action #. */ for ( i = 0; i <= lastdfa; ++i ) { int anum = dfaacc[i].dfaacc_state; int offset = base[i]; chk[offset] = EOB_POSITION; chk[offset - 1] = ACTION_POSITION; nxt[offset - 1] = anum; /* action number */ } for ( i = 0; i <= tblend; ++i ) { if ( chk[i] == EOB_POSITION ) transition_struct_out( 0, base[lastdfa + 1] - i ); else if ( chk[i] == ACTION_POSITION ) transition_struct_out( 0, nxt[i] ); else if ( chk[i] > numecs || chk[i] == 0 ) transition_struct_out( 0, 0 ); /* unused slot */ else /* verify, transition */ transition_struct_out( chk[i], base[nxt[i]] - (i - chk[i]) ); } /* Here's the final, end-of-buffer state. */ transition_struct_out( chk[tblend + 1], nxt[tblend + 1] ); transition_struct_out( chk[tblend + 2], nxt[tblend + 2] ); outn( " };\n" ); /* Table of pointers to start states. */ out_dec( "static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n", lastsc * 2 + 1 ); outn( " {" ); /* } so vi doesn't get confused */ for ( i = 0; i <= lastsc * 2; ++i ) out_dec( " &yy_transition[%d],\n", base[i] ); dataend(); if ( useecs ) genecs(); }
int snstods (int sns[], int numstates, int accset[], int nacc, int hashval, int *newds_addr) { int didsort = 0; int i, j; int newds, *oldsns; for (i = 1; i <= lastdfa; ++i) if (hashval == dhash[i]) { if (numstates == dfasiz[i]) { oldsns = dss[i]; if (!didsort) { /* We sort the states in sns so we * can compare it to oldsns quickly. */ qsort (&sns [1], (size_t) numstates, sizeof (sns [1]), intcmp); didsort = 1; } for (j = 1; j <= numstates; ++j) if (sns[j] != oldsns[j]) break; if (j > numstates) { ++dfaeql; *newds_addr = i; return 0; } ++hshcol; } else ++hshsave; } /* Make a new dfa. */ if (++lastdfa >= current_max_dfas) increase_max_dfas (); newds = lastdfa; dss[newds] = allocate_integer_array (numstates + 1); /* If we haven't already sorted the states in sns, we do so now, * so that future comparisons with it can be made quickly. */ if (!didsort) qsort (&sns [1], (size_t) numstates, sizeof (sns [1]), intcmp); for (i = 1; i <= numstates; ++i) dss[newds][i] = sns[i]; dfasiz[newds] = numstates; dhash[newds] = hashval; if (nacc == 0) { if (reject) dfaacc[newds].dfaacc_set = NULL; else dfaacc[newds].dfaacc_state = 0; accsiz[newds] = 0; } else if (reject) { /* We sort the accepting set in increasing order so the * disambiguating rule that the first rule listed is considered * match in the event of ties will work. */ qsort (&accset [1], (size_t) nacc, sizeof (accset [1]), intcmp); dfaacc[newds].dfaacc_set = allocate_integer_array (nacc + 1); /* Save the accepting set for later */ for (i = 1; i <= nacc; ++i) { dfaacc[newds].dfaacc_set[i] = accset[i]; if (accset[i] <= num_rules) /* Who knows, perhaps a REJECT can yield * this rule. */ rule_useful[accset[i]] = true; } accsiz[newds] = nacc; } else { /* Find lowest numbered rule so the disambiguating rule * will work. */ j = num_rules + 1; for (i = 1; i <= nacc; ++i) if (accset[i] < j) j = accset[i]; dfaacc[newds].dfaacc_state = j; if (j <= num_rules) rule_useful[j] = true; } *newds_addr = newds; return 1; }