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);   
}
示例#2
0
文件: io.c 项目: JSefara/foma
struct fsm *io_net_read(struct io_buf_handle *iobh, char **net_name) {

    char buf[READ_BUF_SIZE];
    struct fsm *net;
    struct fsm_state *fsm;
    
    char *new_symbol;
    int i, items, new_symbol_number, laststate, lineint[5], *cm;
    int extras;
    char last_final = '1';

    if (io_gets(iobh, buf) == 0) {
        return NULL;
    }
    
    net = fsm_create("");

    if (strcmp(buf, "##foma-net 1.0##") != 0) {
	fsm_destroy(net);
        perror("File format error foma!\n");
        return NULL;
    }
    io_gets(iobh, buf);
    if (strcmp(buf, "##props##") != 0) {
        perror("File format error props!\n");
	fsm_destroy(net);
        return NULL;
    }
    /* Properties */
    io_gets(iobh, buf);
    extras = 0;
    sscanf(buf, "%i %i %i %i %i %lld %i %i %i %i %i %i %s", &net->arity, &net->arccount, &net->statecount, &net->linecount, &net->finalcount, &net->pathcount, &net->is_deterministic, &net->is_pruned, &net->is_minimized, &net->is_epsilon_free, &net->is_loop_free, &extras, buf);
    strcpy(net->name, buf);
    *net_name = xxstrdup(buf);
    io_gets(iobh, buf);

    net->is_completed = (extras & 3);
    net->arcs_sorted_in = (extras & 12) >> 2;
    net->arcs_sorted_out = (extras & 48) >> 4;

    /* Sigma */
    while (strcmp(buf, "##sigma##") != 0) { /* Loop until we encounter ##sigma## */
        if (buf[0] == '\0') {
	  printf("File format error at sigma definition!\n");
	  fsm_destroy(net);
	  return NULL;
        }
        io_gets(iobh, buf);
    }

    for (;;) {
        io_gets(iobh, buf);
        if (buf[0] == '#') break;
        if (buf[0] == '\0') continue;
        new_symbol = strstr(buf, " ");
	new_symbol[0] = '\0';
	new_symbol++;
	if (new_symbol[0] == '\0') {
	    sscanf(buf,"%i", &new_symbol_number);
	    sigma_add_number(net->sigma, "\n", new_symbol_number);
	} else {
	    sscanf(buf,"%i", &new_symbol_number);
	    sigma_add_number(net->sigma, new_symbol, new_symbol_number);
	}
    }

    /* States */
    if (strcmp(buf, "##states##") != 0) {
        printf("File format error!\n");
        return NULL;
    }
    net->states = xxmalloc(net->linecount*sizeof(struct fsm_state));
    fsm = net->states;
    laststate = -1;
    for (i=0; ;i++) {
        io_gets(iobh, buf);
        if (buf[0] == '#') break;

        /* scanf is just too slow here */

        //items = sscanf(buf, "%i %i %i %i %i",&lineint[0], &lineint[1], &lineint[2], &lineint[3], &lineint[4]);

        items = explode_line(buf, &lineint[0]);

        switch (items) {
        case 2:
            (fsm+i)->state_no = laststate;
            (fsm+i)->in = lineint[0];
            (fsm+i)->out = lineint[0];
            (fsm+i)->target = lineint[1];
            (fsm+i)->final_state = last_final;
            break;
        case 3:
            (fsm+i)->state_no = laststate;
            (fsm+i)->in = lineint[0];
            (fsm+i)->out = lineint[1];
            (fsm+i)->target = lineint[2];
            (fsm+i)->final_state = last_final;
            break;
        case 4:
            (fsm+i)->state_no = lineint[0];
            (fsm+i)->in = lineint[1];
            (fsm+i)->out = lineint[1];
            (fsm+i)->target = lineint[2];
            (fsm+i)->final_state = lineint[3];
            laststate = lineint[0];
            last_final = lineint[3];
            break;
        case 5:
            (fsm+i)->state_no = lineint[0];
            (fsm+i)->in = lineint[1];
            (fsm+i)->out = lineint[2];
            (fsm+i)->target = lineint[3];
            (fsm+i)->final_state = lineint[4];
            laststate = lineint[0];
            last_final = lineint[4];
            break;
        default:
            printf("File format error\n");
            return NULL;
        }
        if (laststate > 0) {
            (fsm+i)->start_state = 0;
        } else if (laststate == -1) {
            (fsm+i)->start_state = -1;
        } else {
            (fsm+i)->start_state = 1;
        }

    }
    if (strcmp(buf, "##cmatrix##") == 0) {
        cmatrix_init(net);
        cm = net->medlookup->confusion_matrix;
        for (;;) {
            io_gets(iobh, buf);
            if (buf[0] == '#') break;
            sscanf(buf,"%i", &i);
            *cm = i;
            cm++;
        }
    }
    if (strcmp(buf, "##end##") != 0) {
        printf("File format error!\n");
        return NULL;
    }
    return(net);
}