示例#1
0
/*  real recursion computation function */
void e_closure(struct nfa *nfa, struct set *stateset, struct accept **acp)
{
	int state;
	if (!nfa)
		return;

	state = nfastate(nfa);
	/* greedy algorithm: accept as much states as possible */
	if (!nfa->next[0]) {
		if (!nfa->accept)
			errexit("no accept action string");
		if (acp)
			*acp = nfa->accept;
	}

	if (nfa->edge == EG_EPSILON) {
		/* next 0 */
		if (nfa->next[0] &&
			!test_add_set(stateset, nfastate(nfa->next[0])))
			e_closure(nfa->next[0], stateset, acp);
		/* next 1 */
		if (nfa->next[1] &&
			!test_add_set(stateset, nfastate(nfa->next[1])))
			e_closure(nfa->next[1], stateset, acp);
	}
}
示例#2
0
static int initial_e_closure(struct fsm *net) {

    struct fsm_state *fsm;
    int i,j;

    finals = xxcalloc(num_states, sizeof(_Bool));

    num_start_states = 0;
    fsm = net->states;
    
    /* Create lookups for each state */
    for (i=0,j=0; (fsm+i)->state_no != -1; i++) {
        if ((fsm+i)->final_state) {
            finals[(fsm+i)->state_no] = 1;
        }
        /* Add the start states as the initial set */
        if ((op == SUBSET_TEST_STAR_FREE) || ((fsm+i)->start_state)) {
            if (*(e_table+((fsm+i)->state_no)) != mainloop) {
                num_start_states++;
                numss = (fsm+i)->state_no;
                *(e_table+((fsm+i)->state_no)) = mainloop;
                *(temp_move+j) = (fsm+i)->state_no;
                j++;
            }
        }
    }
    mainloop++;
    /* Memoize e-closure(u) */
    if (epsilon_symbol != -1) {
        memoize_e_closure(fsm);
    }
    return(e_closure(j));
}
示例#3
0
/*
 * recursion implemented computation for epsilon closure set from input
 * @dup    if 1, output set realloced
 *         otherwise, epsilon closure set is added into input
 *          and return input
 * @accept accept state
 * @input  start state for computing epsilon closure
 *
 * input only contains sstate
 */
struct set *epsilon_closure(struct set *input, struct accept **acp, int dup)
{
	int start_state[MAXSTACKNFAS];
	int state;
	struct set *output;

	/*
	 * We cannot using e_closure(nfa, output),
	 * because sstate is already in output.
	 */
	if (acp)
		*acp = NULL;

	if (!input)
		return NULL;

	/* set return value(epsilon closure set) */
	output = dup ? dupset(input) : input;

	/* buffering start state int input */
	for (startmember(input), state = 0; state < MAXSTACKNFAS; state++) {
		start_state[state] = nextmember(input);
		if (start_state[state] == -1) {
			state--;
			break;
		}
	}

	if (state >= MAXSTACKNFAS)
		errexit("state stack overflows");
	/* computing epsilon closure of every start state in input set */
	for (; state >= 0; state--)
		e_closure(statenfa(start_state[state]), output, acp);

	return output;
}
示例#4
0
static struct fsm *fsm_subset(struct fsm *net, int operation) {

    int T, U;
    
    if (net->is_deterministic == YES && operation != SUBSET_TEST_STAR_FREE) {
        return(net);
    }
    /* Export this var */
    op = operation;
    fsm_count(net);
    num_states = net->statecount;
    deterministic = 1;
    init(net);
    nhash_init((num_states < 12) ? 6 : num_states/2);
    
    T = initial_e_closure(net);

    int_stack_clear();
    
    if (deterministic == 1 && epsilon_symbol == -1 && num_start_states == 1 && numss == 0) {
        net->is_deterministic = YES;
        net->is_epsilon_free = YES;
        nhash_free(table, nhash_tablesize);
        xxfree(T_ptr);
        xxfree(e_table);
        xxfree(trans_list);
        xxfree(trans_array);
        xxfree(double_sigma_array);
        xxfree(single_sigma_array);
        xxfree(finals);
        xxfree(temp_move);
        xxfree(set_table);
        return(net);
    }

    if (operation == SUBSET_EPSILON_REMOVE && epsilon_symbol == -1) {
        net->is_epsilon_free = YES;
        nhash_free(table, nhash_tablesize);
        xxfree(T_ptr);
        xxfree(e_table);
        xxfree(trans_list);
        xxfree(trans_array);
        xxfree(double_sigma_array);
        xxfree(single_sigma_array);
        xxfree(finals);
        xxfree(temp_move);
        xxfree(set_table);
        return(net);
    }

    if (operation == SUBSET_TEST_STAR_FREE) {
        fsm_state_init(sigma_max(net->sigma)+1);
        star_free_mark = 0;
    } else {
        fsm_state_init(sigma_max(net->sigma));
        xxfree(net->states);
    }

    /* init */

    do {
        int i, j, tail, setsize, *theset, stateno, has_trans, minsym, next_minsym, trgt, symbol_in, symbol_out;
        struct trans_list *transitions;
        struct trans_array *tptr;

        fsm_state_set_current_state(T, (T_ptr+T)->finalstart, T == 0 ? 1 : 0);
        
        /* Prepare set */
        setsize = (T_ptr+T)->size;
        theset = set_table+(T_ptr+T)->set_offset;
        minsym = INT_MAX;
        has_trans = 0;
        for (i = 0; i < setsize; i++) {
            stateno = *(theset+i);
            tptr = trans_array+stateno;
            tptr->tail = 0;
            if (tptr->size == 0)
                continue;
            if ((tptr->transitions)->inout < minsym) {
                minsym = (tptr->transitions)->inout;
                has_trans = 1;
            }
        }
        if (!has_trans) {
            /* close state */
            fsm_state_end_state();
            continue;
        }
        
        /* While set not empty */

        for (next_minsym = INT_MAX; minsym != INT_MAX ; minsym = next_minsym, next_minsym = INT_MAX) {
            theset = set_table+(T_ptr+T)->set_offset;
            
            for (i = 0, j = 0 ; i < setsize; i++) {
                
                stateno = *(theset+i);
                tptr = trans_array+stateno;
                tail = tptr->tail;
                transitions = (tptr->transitions)+tail;
                
                while (tail < tptr->size &&  transitions->inout == minsym) {
                    trgt = transitions->target;
                    if (*(e_table+(trgt)) != mainloop) {
                        *(e_table+(trgt)) = mainloop;
                        *(temp_move+j) = trgt;
                        j++;
                        
                        if (operation == SUBSET_EPSILON_REMOVE) {
                            mainloop++;
                            if ((U = e_closure(j)) != -1) {
                                single_symbol_to_symbol_pair(minsym, &symbol_in, &symbol_out);
                                fsm_state_add_arc(T, symbol_in, symbol_out, U, (T_ptr+T)->finalstart, T == 0 ? 1 : 0);
                                j = 0;
                            }
                        }
                    }
                    tail++;
                    transitions++;
                }
                
                tptr->tail = tail;
                
                if (tail == tptr->size)
                    continue;
                /* Check next minsym */
                if (transitions->inout < next_minsym) {
                    next_minsym = transitions->inout;
                }
            }
            if (operation == SUBSET_DETERMINIZE) {
                mainloop++;
                if ((U = e_closure(j)) != -1) {
                    single_symbol_to_symbol_pair(minsym, &symbol_in, &symbol_out);
                    fsm_state_add_arc(T, symbol_in, symbol_out, U, (T_ptr+T)->finalstart, T == 0 ? 1 : 0);
                }
            }
            if (operation == SUBSET_TEST_STAR_FREE) {
                mainloop++;
                if ((U = e_closure(j)) != -1) {
                    single_symbol_to_symbol_pair(minsym, &symbol_in, &symbol_out);                   
                    fsm_state_add_arc(T, symbol_in, symbol_out, U, (T_ptr+T)->finalstart, T == 0 ? 1 : 0);
                    if (star_free_mark == 1) {
                        //fsm_state_add_arc(T, maxsigma, maxsigma, U, (T_ptr+T)->finalstart, T == 0 ? 1 : 0);
                        star_free_mark = 0;
                    }
                }
            }
        }
        /* end state */
        fsm_state_end_state();
    } while ((T = next_unmarked()) != -1);
    
    /* wrapup() */
    nhash_free(table, nhash_tablesize);
    xxfree(set_table);
    xxfree(T_ptr);
    xxfree(temp_move);
    xxfree(e_table);
    xxfree(trans_list);
    xxfree(trans_array);
    
    if (epsilon_symbol != -1)
        e_closure_free();
    xxfree(double_sigma_array);
    xxfree(single_sigma_array);
    xxfree(finals);
    fsm_state_close(net);
    return(net);
}