struct fsm *flag_twosided(struct fsm *net) { struct fsm_state *fsm; struct sigma *sigma; int i, j, tail, *isflag, maxsigma, maxstate, newarcs, change; /* Enforces twosided flag diacritics */ /* Mark flag symbols */ maxsigma = sigma_max(net->sigma); isflag = xxcalloc(maxsigma+1, sizeof(int)); fsm = net->states; for (sigma = net->sigma ; sigma != NULL; sigma = sigma->next) { if (flag_check(sigma->symbol)) { *(isflag+sigma->number) = 1; } else { *(isflag+sigma->number) = 0; } } maxstate = 0; change = 0; for (i = 0, newarcs = 0; (fsm+i)->state_no != -1 ; i++) { maxstate = (fsm+i)->state_no > maxstate ? (fsm+i)->state_no : maxstate; if ((fsm+i)->target == -1) continue; if (*(isflag+(fsm+i)->in) && (fsm+i)->out == EPSILON) { change = 1; (fsm+i)->out = (fsm+i)->in; } else if (*(isflag+(fsm+i)->out) && (fsm+i)->in == EPSILON) { change = 1; (fsm+i)->in = (fsm+i)->out; } if ((*(isflag+(fsm+i)->in) || *(isflag+(fsm+i)->out)) && (fsm+i)->in != (fsm+i)->out) { newarcs++; } } if (newarcs == 0) { if (change == 1) { net->is_deterministic = UNK; net->is_minimized = UNK; net->is_pruned = UNK; return fsm_topsort(fsm_minimize(net)); } return net; } net->states = xxrealloc(net->states, sizeof(struct fsm)*(i+newarcs)); fsm = net->states; tail = j = i; maxstate++; for (i = 0; i < tail; i++) { if ((fsm+i)->target == -1) continue; if ((*(isflag+(fsm+i)->in) || *(isflag+(fsm+i)->out)) && (fsm+i)->in != (fsm+i)->out) { if (*(isflag+(fsm+i)->in) && !*(isflag+(fsm+i)->out)) { j = add_fsm_arc(fsm, j, maxstate, EPSILON, (fsm+i)->out, (fsm+i)->target, 0, 0); (fsm+i)->out = (fsm+i)->in; (fsm+i)->target = maxstate; maxstate++; } else if (*(isflag+(fsm+i)->out) && !*(isflag+(fsm+i)->in)) { j = add_fsm_arc(fsm, j, maxstate, (fsm+i)->out, (fsm+i)->out, (fsm+i)->target, 0, 0); (fsm+i)->out = EPSILON; (fsm+i)->target = maxstate; maxstate++; } else if (*(isflag+(fsm+i)->in) && *(isflag+(fsm+i)->out)) { j = add_fsm_arc(fsm, j, maxstate, (fsm+i)->out, (fsm+i)->out, (fsm+i)->target, 0, 0); (fsm+i)->out = (fsm+i)->in; (fsm+i)->target = maxstate; maxstate++; } } } /* Add sentinel */ add_fsm_arc(fsm, j, -1, -1, -1, -1, -1, -1); net->is_deterministic = UNK; net->is_minimized = UNK; return fsm_topsort(fsm_minimize(net)); }
struct fsm *fsm_read_prolog (char *filename) { char buf [1024], temp [1024], in [128], out[128], *temp_ptr, *temp_ptr2; int arity, source, target, has_net; struct fsm *outnet; struct fsm_construct_handle *outh = NULL; FILE *prolog_file; has_net = 0; prolog_file = fopen(filename, "r"); if (prolog_file == NULL) { return NULL; } while (fgets(buf, 1023, prolog_file) != NULL) { if (strstr(buf, "network(") == buf) { /* Extract network name */ if (has_net == 1) { perror("WARNING: prolog file contains multiple nets. Only returning the first one.\n"); break; } else { has_net = 1; } temp_ptr = strstr(buf, "network(")+8; temp_ptr2 = strstr(buf, ")."); strncpy(temp, temp_ptr, (temp_ptr2 - temp_ptr)); temp[(temp_ptr2-temp_ptr)] = '\0'; /* Start network */ outh = fsm_construct_init(temp); } if (strstr(buf, "final(") == buf) { temp_ptr = strstr(buf, " "); temp_ptr++; temp_ptr2 = strstr(temp_ptr, ")."); strncpy(temp, temp_ptr, (temp_ptr2 - temp_ptr)); temp[(temp_ptr2-temp_ptr)] = '\0'; fsm_construct_set_final(outh, atoi(temp)); } if (strstr(buf, "symbol(") == buf) { temp_ptr = strstr(buf, ", \"")+3; temp_ptr2 = strstr(temp_ptr, "\")."); strncpy(temp, temp_ptr, (temp_ptr2 - temp_ptr)); temp[(temp_ptr2-temp_ptr)] = '\0'; if (strcmp(temp, "%0") == 0) strcpy(temp, "0"); //printf("special: %s\n",temp); if (fsm_construct_check_symbol(outh, temp) == -1) { fsm_construct_add_symbol(outh, temp); } continue; } if (strstr(buf, "arc(") == buf) { in[0] = '\0'; out[0] = '\0'; if (strstr(buf, "\":\"") == NULL || strstr(buf, ", \":\").") != NULL) { arity = 1; } else { arity = 2; } /* Get source */ temp_ptr = strstr(buf, " "); temp_ptr++; temp_ptr2 = strstr(temp_ptr, ","); strncpy(temp, temp_ptr, (temp_ptr2 - temp_ptr)); temp[(temp_ptr2-temp_ptr)] = '\0'; source = atoi(temp); /* Get target */ temp_ptr = strstr(temp_ptr2, " "); temp_ptr++; temp_ptr2 = strstr(temp_ptr, ","); strncpy(temp, temp_ptr, (temp_ptr2 - temp_ptr)); temp[(temp_ptr2-temp_ptr)] = '\0'; target = atoi(temp); temp_ptr = strstr(temp_ptr2, "\""); temp_ptr++; if (arity == 2) { temp_ptr2 = strstr(temp_ptr, "\":"); } else { temp_ptr2 = strstr(temp_ptr, "\")."); } strncpy(in, temp_ptr, (temp_ptr2 - temp_ptr)); in[(temp_ptr2 - temp_ptr)] = '\0'; if (arity == 2) { temp_ptr = strstr(temp_ptr2, ":\""); temp_ptr += 2; temp_ptr2 = strstr(temp_ptr, "\")."); strncpy(out, temp_ptr, (temp_ptr2 - temp_ptr)); out[(temp_ptr2 - temp_ptr)] = '\0'; } if (arity == 1 && (strcmp(in, "?") == 0)) { strcpy(in,"@_IDENTITY_SYMBOL_@"); } if (arity == 2 && (strcmp(in, "?") == 0)) { strcpy(in,"@_UNKNOWN_SYMBOL_@"); } if (arity == 2 && (strcmp(out, "?") == 0)) { strcpy(out,"@_UNKNOWN_SYMBOL_@"); } if (strcmp(in, "0") == 0) { strcpy(in,"@_EPSILON_SYMBOL_@"); } if (strcmp(out, "0") == 0) { strcpy(out,"@_EPSILON_SYMBOL_@"); } if (strcmp(in, "%0") == 0) { strcpy(in,"0"); } if (strcmp(out, "%0") == 0) { strcpy(out,"0"); } if (strcmp(in, "%?") == 0) { strcpy(in,"?"); } if (strcmp(out, "%?") == 0) { strcpy(out,"?"); } if (arity == 1) { fsm_construct_add_arc(outh, source, target, in, in); } else { fsm_construct_add_arc(outh, source, target, in, out); } } } fclose(prolog_file); if (has_net == 1) { fsm_construct_set_initial(outh, 0); outnet = fsm_construct_done(outh); fsm_topsort(outnet); return(outnet); } else { return(NULL); } }