Ejemplo n.º 1
0
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);   
}
Ejemplo n.º 2
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);
}