예제 #1
0
파일: tblcmp.c 프로젝트: Kampbell/ReFlex
void
mkdeftbl(void)
{
    int i;

    jamstate = lastdfa + 1;

    ++tblend;			/* room for transition on end-of-buffer character */

    while (tblend + numecs >= current_max_xpairs)
	expand_nxt_chk();

    /* Add in default end-of-buffer transition. */
    nxt[tblend] = end_of_buffer_state;
    chk[tblend] = jamstate;

    for (i = 1; i <= numecs; ++i) {
	nxt[tblend + i] = 0;
	chk[tblend + i] = jamstate;
    }

    jambase = tblend;

    base[jamstate] = jambase;
    def[jamstate] = 0;

    tblend += numecs;
    ++numtemps;
}
예제 #2
0
void    mk1tbl (int state, int sym, int onenxt, int onedef)
{
	if (firstfree < sym)
		firstfree = sym;

	while (chk[firstfree] != 0)
		if (++firstfree >= current_max_xpairs)
			expand_nxt_chk ();

	base[state] = firstfree - sym;
	def[state] = onedef;
	chk[firstfree] = state;
	nxt[firstfree] = onenxt;

	if (firstfree > tblend) {
		tblend = firstfree++;

		if (firstfree >= current_max_xpairs)
			expand_nxt_chk ();
	}
}
예제 #3
0
파일: gen.c 프로젝트: EgoIncarnate/mozart
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();
	}
예제 #4
0
파일: tblcmp.c 프로젝트: Kampbell/ReFlex
/* mkentry - create base/def and nxt/chk entries for transition array
 *
 * synopsis
 *   int state[numchars + 1], numchars, statenum, deflink, totaltrans;
 *   mkentry( state, numchars, statenum, deflink, totaltrans );
 *
 * "state" is a transition array "numchars" characters in size, "statenum"
 * is the offset to be used into the base/def tables, and "deflink" is the
 * entry to put in the "def" table entry.  If "deflink" is equal to
 * "JAMSTATE", then no attempt will be made to fit zero entries of "state"
 * (i.e., jam entries) into the table.  It is assumed that by linking to
 * "JAMSTATE" they will be taken care of.  In any case, entries in "state"
 * marking transitions to "SAME_TRANS" are treated as though they will be
 * taken care of by whereever "deflink" points.  "totaltrans" is the total
 * number of transitions out of the state.  If it is below a certain threshold,
 * the tables are searched for an interior spot that will accommodate the
 * state array.
 */
void
mkentry(int *state, int numchars, int statenum, int deflink, int totaltrans)
{
    int minec, maxec, i, baseaddr;
    int tblbase, tbllast;

    if (totaltrans == 0) {	/* there are no out-transitions */
	if (deflink == JAMSTATE)
	    base[statenum] = JAMSTATE;
	else
	    base[statenum] = 0;

	def[statenum] = deflink;
	return;
    }

    for (minec = 1; minec <= numchars; ++minec) {
	if (state[minec] != SAME_TRANS)
	    if (state[minec] != 0 || deflink != JAMSTATE)
		break;
    }

    if (totaltrans == 1) {
	/* There's only one out-transition.  Save it for later to fill
	 * in holes in the tables.
	 */
	stack1(statenum, minec, state[minec], deflink);
	return;
    }

    for (maxec = numchars; maxec > 0; --maxec) {
	if (state[maxec] != SAME_TRANS)
	    if (state[maxec] != 0 || deflink != JAMSTATE)
		break;
    }

    /* Whether we try to fit the state table in the middle of the table
     * entries we have already generated, or if we just take the state
     * table at the end of the nxt/chk tables, we must make sure that we
     * have a valid base address (i.e., non-negative).  Note that
     * negative base addresses dangerous at run-time (because indexing
     * the nxt array with one and a low-valued character will access
     * memory before the start of the array.
     */

    /* Find the first transition of state that we need to worry about. */
    if (totaltrans * 100 <= numchars * INTERIOR_FIT_PERCENTAGE) {
	/* Attempt to squeeze it into the middle of the tables. */
	baseaddr = firstfree;

	while (baseaddr < minec) {
	    /* Using baseaddr would result in a negative base
	     * address below; find the next free slot.
	     */
	    for (++baseaddr; chk[baseaddr] != 0; ++baseaddr) ;
	}

	while (baseaddr + maxec - minec + 1 >= current_max_xpairs)
	    expand_nxt_chk();

	for (i = minec; i <= maxec; ++i)
	    if (state[i] != SAME_TRANS &&
		(state[i] != 0 || deflink != JAMSTATE) &&
		chk[baseaddr + i - minec] != 0) {	/* baseaddr unsuitable - find another */
		for (++baseaddr;
		     baseaddr < current_max_xpairs &&
		     chk[baseaddr] != 0; ++baseaddr) ;

		while (baseaddr + maxec - minec + 1 >=
		       current_max_xpairs)
		    expand_nxt_chk();

		/* Reset the loop counter so we'll start all
		 * over again next time it's incremented.
		 */

		i = minec - 1;
	    }
    }

    else {
	/* Ensure that the base address we eventually generate is
	 * non-negative.
	 */
	baseaddr = MAX(tblend + 1, minec);
    }

    tblbase = baseaddr - minec;
    tbllast = tblbase + maxec;

    while (tbllast + 1 >= current_max_xpairs)
	expand_nxt_chk();

    base[statenum] = tblbase;
    def[statenum] = deflink;

    for (i = minec; i <= maxec; ++i)
	if (state[i] != SAME_TRANS)
	    if (state[i] != 0 || deflink != JAMSTATE) {
		nxt[tblbase + i] = state[i];
		chk[tblbase + i] = statenum;
	    }

    if (baseaddr == firstfree)
	/* Find next free slot in tables. */
	for (++firstfree; chk[firstfree] != 0; ++firstfree) ;

    tblend = MAX(tblend, tbllast);
}
예제 #5
0
파일: tblcmp.c 프로젝트: Kampbell/ReFlex
/* find_table_space - finds a space in the table for a state to be placed
 *
 * synopsis
 *     int *state, numtrans, block_start;
 *     int find_table_space();
 *
 *     block_start = find_table_space( state, numtrans );
 *
 * State is the state to be added to the full speed transition table.
 * Numtrans is the number of out-transitions for the state.
 *
 * find_table_space() returns the position of the start of the first block (in
 * chk) able to accommodate the state
 *
 * In determining if a state will or will not fit, find_table_space() must take
 * into account the fact that an end-of-buffer state will be added at [0],
 * and an action number will be added in [-1].
 */
int
find_table_space(int *state, int numtrans)
{
    /* Firstfree is the position of the first possible occurrence of two
     * consecutive unused records in the chk and nxt arrays.
     */
    int i;
    int *state_ptr, *chk_ptr;
    int *ptr_to_last_entry_in_state;

    /* If there are too many out-transitions, put the state at the end of
     * nxt and chk.
     */
    if (numtrans > MAX_XTIONS_FULL_INTERIOR_FIT) {
	/* If table is empty, return the first available spot in
	 * chk/nxt, which should be 1.
	 */
	if (tblend < 2)
	    return 1;

	/* Start searching for table space near the end of
	 * chk/nxt arrays.
	 */
	i = tblend - numecs;
    }

    else
	/* Start searching for table space from the beginning
	 * (skipping only the elements which will definitely not
	 * hold the new state).
	 */
	i = firstfree;

    while (1)			/* loops until a space is found */
    {
	while (i + numecs >= current_max_xpairs)
	    expand_nxt_chk();

	/* Loops until space for end-of-buffer and action number
	 * are found.
	 */
	while (1) {
	    /* Check for action number space. */
	    if (chk[i - 1] == 0) {
		/* Check for end-of-buffer space. */
		if (chk[i] == 0)
		    break;

		else
		    /* Since i != 0, there is no use
		     * checking to see if (++i) - 1 == 0,
		     * because that's the same as i == 0,
		     * so we skip a space.
		     */
		    i += 2;
	    }

	    else
		++i;

	    while (i + numecs >= current_max_xpairs)
		expand_nxt_chk();
	}

	/* If we started search from the beginning, store the new
	 * firstfree for the next call of find_table_space().
	 */
	if (numtrans <= MAX_XTIONS_FULL_INTERIOR_FIT)
	    firstfree = i + 1;

	/* Check to see if all elements in chk (and therefore nxt)
	 * that are needed for the new state have not yet been taken.
	 */

	state_ptr = &state[1];
	ptr_to_last_entry_in_state = &chk[i + numecs + 1];

	for (chk_ptr = &chk[i + 1];
	     chk_ptr != ptr_to_last_entry_in_state; ++chk_ptr)
	    if (*(state_ptr++) != 0 && *chk_ptr != 0)
		break;

	if (chk_ptr == ptr_to_last_entry_in_state)
	    return i;

	else
	    ++i;
    }
}