FSM* concat(FSM* f1, FSM* f2) { unsigned n1 = f1 ->numberStates; unsigned n2 = f2 ->numberStates; unsigned n = n1 + n2 - 1; FSM* fsm = allocateFSM(n); move(fsm, f1, 0); move(fsm, f2, n1 - 1); freeFsm(f1); freeFsm(f2); return fsm; }
FSM* alternative(FSM* f1, FSM* f2) { unsigned n1 = f1 ->numberStates; unsigned n2 = f2 ->numberStates; unsigned n = n1 + n2 + 2; FSM* fsm = allocateFSM(n); // new start state pointing to the start states if f1 and f2 epsTransition(fsm, 0, 1, n1 + 1); move(fsm, f1, 1); // create an epsilon transition for the last state of f1 epsTransition(fsm, n1, n - 1, n - 1); move(fsm, f2, n1 + 1); // create an epsilon transition for the last state of f2 epsTransition(fsm, n - 2, n - 1, n - 1); // let the last state point to itself epsTransition(fsm, n - 1, n - 1, n - 1); freeFsm(f1); freeFsm(f2); return fsm; }
FSM* closure(FSM* f) { unsigned n = f->numberStates; FSM* fsm = allocateFSM(n+2); // new start state epsTransition(fsm, 0, 1, n + 1); // copy the first fsm move(fsm, f, 1); // create epsilon transition from the last state of f // to the new final state and to the start state of f epsTransition(fsm, n, n + 1, 1); // let the last state point to itself epsTransition(fsm, n + 1, n + 1, n + 1); freeFsm(f); return fsm; }
int main() { FSM* fsm = concat(closure(alternative(createCharacter('a'), createCharacter('b'))), concat(createCharacter('a'), concat(createCharacter('b'), createCharacter('b')))); printFsm(fsm); char buffer[100]; do { printf("String: "); scanf("%s", buffer); if (simulate(fsm, buffer)) { printf("%s wurde akzeptiert.\n", buffer); } else { printf("%s wurde nicht akzeptiert.\n", buffer); } } while (buffer[1]); freeFsm(fsm); }
int main(int argc, char *const *argv) { FILE *data = NULL; struct parameters p; char o, *tok, tmp[256]; word_t word; struct d_entry *d_entry; p.delimiters = NULL; STAILQ_INIT(&p.dictionary); // Initialisation des parametres while((o = getopt (argc, argv, "a:A:d:D:w:W:hHvV")) != -1) switch(o) { case 'w': case 'W': tok = strtok(optarg, " "); do { if((d_entry = (struct d_entry *) malloc(sizeof(struct d_entry)))) if((d_entry->string = (char *) calloc((strlen(tok) + 1), sizeof(char)))) { strcpy(d_entry->string, tok); STAILQ_INSERT_TAIL(&p.dictionary, d_entry, entries); } else { fprintf( stderr, "%s: Unable to create a dictionary entry for the word \"%s\": %s\n", *argv, tok, strerror(errno) ); free(d_entry); } else fprintf( stderr, "%s: Unable to create a dictionary entry for the word \"%s\": %s\n", *argv, tok, strerror(errno) ); } while((tok = strtok(NULL, " "))); break; case 'd': case 'D': p.delimiters = optarg; break; case 'h': case 'H': switch(system("cat help.txt")) { case 1: fprintf(stderr, "%s: \"help.txt\" does not exist", *argv); case -1: return EXIT_FAILURE; default: return EXIT_SUCCESS; break; } break; case 'v': case 'V': verbose = true; break; case '?': default: fprintf(stderr, "Usage: %s %s\n", *argv, USAGE); return EXIT_FAILURE; break; } // Chargement des dictionnaires while(optind < argc - 1) { if(!(data = fopen(argv[optind], "r"))) fprintf(stderr, "%s: %s\n", *argv, strerror(errno)); else { addWords(data, &p.dictionary); } fclose(data); optind++; } if(optind >= argc) { fprintf(stderr, "Usage: %s %s\n", *argv, USAGE); return EXIT_FAILURE; } // Chargement de l'automate if(!(data = fopen(argv[optind], "r"))) { fprintf(stderr, "%s: %s: %s\n", *argv, argv[optind], strerror(errno)); return EXIT_FAILURE; } if(!parse(data, &(p.fsm))) { fprintf(stderr, "%s: Unable to parse the automaton file\n", *argv); fclose(data); return EXIT_FAILURE; } fclose(data); // Lecture de mots sur l'entree standard if(STAILQ_EMPTY(&p.dictionary)) { while(printf("> "), scanf("%255[^\n]s\n", tmp)) { word = mkword(tmp, p.delimiters); printf("%s - %srecognized by the automaton\n", tmp, recognize(&p.fsm, word) ? "" : "un"); wfree(word); getchar(); } } // Lecture du dictionnaire while((d_entry = STAILQ_FIRST(&p.dictionary))) { word = mkword(d_entry->string, p.delimiters); printf("%s - %srecognized by the automaton\n", d_entry->string, recognize(&p.fsm, word) ? "" : "un"); wfree(word); STAILQ_REMOVE_HEAD(&p.dictionary, entries); free(d_entry->string); free(d_entry); } freeFsm(&(p.fsm)); return EXIT_SUCCESS; }