struct fsm *fsm_construct_done(struct fsm_construct_handle *handle) { int i; struct fsm *net; struct fsm_state_list *sl; struct fsm_trans_list *trans, *transnext; struct fsm_sigma_hash *sigmahash, *sigmahashnext; sl = handle->fsm_state_list; if (handle->maxstate == -1 || handle->numfinals == 0) { return(fsm_empty_set()); } fsm_state_init((handle->maxsigma)+1); for (i=0; i <= handle->maxstate; i++) { fsm_state_set_current_state(i, (sl+i)->is_final, (sl+i)->is_initial); for (trans = (sl+i)->fsm_trans_list; trans != NULL; trans = trans->next) { fsm_state_add_arc(i, trans->in, trans->out, trans->target, (sl+i)->is_final, (sl+i)->is_initial); } fsm_state_end_state(); } net = fsm_create(""); xxfree(net->sigma); fsm_state_close(net); net->sigma = fsm_construct_convert_sigma(handle); if (handle->name != NULL) { strncpy(net->name, handle->name, 40); xxfree(handle->name); } else { sprintf(net->name, "%X",rand()); } /* Free transitions */ for (i=0; i < handle->fsm_state_list_size; i++) { trans = (((handle->fsm_state_list)+i)->fsm_trans_list); while (trans != NULL) { transnext = trans->next; xxfree(trans); trans = transnext; } } /* Free hash table */ for (i=0; i < SIGMA_HASH_SIZE; i++) { sigmahash = (((handle->fsm_sigma_hash)+i)->next); while (sigmahash != NULL) { sigmahashnext = sigmahash->next; xxfree(sigmahash); sigmahash = sigmahashnext; } } xxfree(handle->fsm_sigma_list); xxfree(handle->fsm_sigma_hash); xxfree(handle->fsm_state_list); xxfree(handle); sigma_sort(net); return(net); }
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); }