Beispiel #1
0
int mkstate(int sym)
{
    if ( ++lastnfa >= current_mns )
	{
	if ( (current_mns += MNS_INCREMENT) >= MAXIMUM_MNS )
	    lerrif( "input rules are too complicated (>= %d NFA states)",
		    current_mns );
	
	++num_reallocs;

	firstst = reallocate_integer_array( firstst, current_mns );
	lastst = reallocate_integer_array( lastst, current_mns );
	finalst = reallocate_integer_array( finalst, current_mns );
	transchar = reallocate_integer_array( transchar, current_mns );
	trans1 = reallocate_integer_array( trans1, current_mns );
	trans2 = reallocate_integer_array( trans2, current_mns );
	accptnum = reallocate_integer_array( accptnum, current_mns );
	assoc_rule = reallocate_integer_array( assoc_rule, current_mns );
	state_type = reallocate_integer_array( state_type, current_mns );
	}

    firstst[lastnfa] = lastnfa;
    finalst[lastnfa] = lastnfa;
    lastst[lastnfa] = lastnfa;
    transchar[lastnfa] = sym;
    trans1[lastnfa] = NO_TRANSITION;
    trans2[lastnfa] = NO_TRANSITION;
    accptnum[lastnfa] = NIL;
    assoc_rule[lastnfa] = num_rules;
    state_type[lastnfa] = current_state_type;

    /* fix up equivalence classes base on this transition.  Note that any
     * character which has its own transition gets its own equivalence class.
     * Thus only characters which are only in character classes have a chance
     * at being in the same equivalence class.  E.g. "a|b" puts 'a' and 'b'
     * into two different equivalence classes.  "[ab]" puts them in the same
     * equivalence class (barring other differences elsewhere in the input).
     */

    if ( sym < 0 )
	{
	/* we don't have to update the equivalence classes since that was
	 * already done when the ccl was created for the first time
	 */
	}

    else if ( sym == SYM_EPSILON )
	++numeps;

    else
	{
	if ( useecs )
	    /* map NUL's to csize */
	    mkechar( sym ? sym : csize, nextecm, ecgroup );
	}

    return ( lastnfa );
    }
Beispiel #2
0
void sympartition (int ds[], int numstates, int symlist[], int duplist[])
{
	int     tch, i, j, k, ns, dupfwd[CSIZE + 1], lenccl, cclp, ich;

	/* Partitioning is done by creating equivalence classes for those
	 * characters which have out-transitions from the given state.  Thus
	 * we are really creating equivalence classes of equivalence classes.
	 */

	for (i = 1; i <= numecs; ++i) {	/* initialize equivalence class list */
		duplist[i] = i - 1;
		dupfwd[i] = i + 1;
	}

	duplist[1] = NIL;
	dupfwd[numecs] = NIL;

	for (i = 1; i <= numstates; ++i) {
		ns = ds[i];
		tch = transchar[ns];

		if (tch != SYM_EPSILON) {
			if (tch < -lastccl || tch >= csize) {
				flexfatal (_
					   ("bad transition character detected in sympartition()"));
			}

			if (tch >= 0) {	/* character transition */
				int     ec = ecgroup[tch];

				mkechar (ec, dupfwd, duplist);
				symlist[ec] = 1;
			}

			else {	/* character class */
				tch = -tch;

				lenccl = ccllen[tch];
				cclp = cclmap[tch];
				mkeccl (ccltbl + cclp, lenccl, dupfwd,
					duplist, numecs, NUL_ec);

				if (cclng[tch]) {
					j = 0;

					for (k = 0; k < lenccl; ++k) {
						ich = ccltbl[cclp + k];

						if (ich == 0)
							ich = NUL_ec;

						for (++j; j < ich; ++j)
							symlist[j] = 1;
					}

					for (++j; j <= numecs; ++j)
						symlist[j] = 1;
				}

				else
					for (k = 0; k < lenccl; ++k) {
						ich = ccltbl[cclp + k];

						if (ich == 0)
							ich = NUL_ec;

						symlist[ich] = 1;
					}
			}
		}
	}
}