mirror of
https://github.com/Hizenberg469/Finite-State-Machine.git
synced 2026-04-20 00:52:24 +03:00
Phase 2 - FSM execution algorithm done
This commit is contained in:
398
app.c
398
app.c
@@ -3,74 +3,15 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "fsm.h"
|
#include "fsm.h"
|
||||||
|
|
||||||
#define MAX_FSM_STATE 24
|
|
||||||
|
|
||||||
#define modify_string(state,num) #state ## #num
|
#define modify_string(state,num) #state ## #num
|
||||||
#define modify_var(state,num) state ## num
|
#define modify_var(state,num) state ## num
|
||||||
|
|
||||||
state_t *fsm_states[MAX_FSM_STATE];
|
|
||||||
|
|
||||||
|
|
||||||
void print_fsm(fsm_t *fsm){
|
fsm_t *
|
||||||
|
fsm_end_with_strict_pattern_01_or_10(){
|
||||||
|
|
||||||
printf("FSM name : %s\n", fsm->fsm_name);
|
fsm_t *fsm = create_new_fsm("FSM_1", "0,1",2);
|
||||||
printf("States : ");
|
|
||||||
char state[6];
|
|
||||||
for(unsigned int i = 0 ; i < fsm->state_count ; i++ ){
|
|
||||||
sprintf(state,"q%1d",i);
|
|
||||||
printf("%s", state);
|
|
||||||
|
|
||||||
if( i < fsm->state_count - 1 )
|
|
||||||
printf(", ");
|
|
||||||
}
|
|
||||||
putchar('\n');
|
|
||||||
|
|
||||||
printf("Alphabets : %s\n", fsm->alphabet);
|
|
||||||
printf("Initial State : %s\n", fsm->initial_state->state_name);
|
|
||||||
printf("Final States : %s\n", fsm->final_states);
|
|
||||||
|
|
||||||
printf("Transition Table :\n");
|
|
||||||
|
|
||||||
printf(" | 1 0 \n");
|
|
||||||
printf("------------------------\n");
|
|
||||||
|
|
||||||
|
|
||||||
char state1[6] = {0};
|
|
||||||
char state2[6] = {0};
|
|
||||||
char state3[6] = {0};
|
|
||||||
|
|
||||||
tt_t *table_ptr = NULL;
|
|
||||||
tt_entry_t *entry_ptr = NULL;
|
|
||||||
for( unsigned int i = 0 ; i < fsm->state_count ; i++ ){
|
|
||||||
|
|
||||||
strncpy(state1, fsm_states[i]->state_name,
|
|
||||||
strlen(fsm_states[i]->state_name));
|
|
||||||
|
|
||||||
table_ptr = &(fsm_states[i]->state_trans_table);
|
|
||||||
FSM_ITERATE_TRANS_TABLE_BEGIN(table_ptr, entry_ptr){
|
|
||||||
|
|
||||||
if( is_tt_entry_empty(entry_ptr) == FSM_FALSE ){
|
|
||||||
if( strcmp(entry_ptr->transition_key, "1") == 0 ){
|
|
||||||
strncpy(state2, entry_ptr->next_state->state_name,
|
|
||||||
strlen(entry_ptr->next_state->state_name));
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
strncpy(state3, entry_ptr->next_state->state_name,
|
|
||||||
strlen(entry_ptr->next_state->state_name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}FSM_ITERATE_TRANS_TABLE_END(table_ptr, entry_ptr)
|
|
||||||
|
|
||||||
printf(" %s | %s %s \n", state1, state2, state3);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
|
|
||||||
fsm_t *fsm = create_new_fsm("FSM_1", "0,1");
|
|
||||||
|
|
||||||
//States
|
//States
|
||||||
state_t *q0 = create_new_state("q0", FSM_FALSE, "FSM_1", fsm);
|
state_t *q0 = create_new_state("q0", FSM_FALSE, "FSM_1", fsm);
|
||||||
@@ -78,10 +19,10 @@ int main(){
|
|||||||
state_t *q2 = create_new_state("q2", FSM_TRUE, "FSM_1", fsm);
|
state_t *q2 = create_new_state("q2", FSM_TRUE, "FSM_1", fsm);
|
||||||
state_t *q3 = create_new_state("q3", FSM_FALSE, "FSM_1", fsm);
|
state_t *q3 = create_new_state("q3", FSM_FALSE, "FSM_1", fsm);
|
||||||
|
|
||||||
fsm_states[0] = q0;
|
fsm->states[0] = q0;
|
||||||
fsm_states[1] = q1;
|
fsm->states[1] = q1;
|
||||||
fsm_states[2] = q2;
|
fsm->states[2] = q2;
|
||||||
fsm_states[3] = q3;
|
fsm->states[3] = q3;
|
||||||
|
|
||||||
set_fsm_initial_state(fsm, q0);
|
set_fsm_initial_state(fsm, q0);
|
||||||
|
|
||||||
@@ -133,8 +74,331 @@ int main(){
|
|||||||
1,
|
1,
|
||||||
q3);
|
q3);
|
||||||
|
|
||||||
|
return fsm;
|
||||||
|
}
|
||||||
|
|
||||||
print_fsm(fsm);
|
fsm_t *
|
||||||
|
fsm_end_with_00_or_11(){
|
||||||
|
|
||||||
|
fsm_t *fsm = create_new_fsm("FSM_2", "0,1",2);
|
||||||
|
|
||||||
|
state_t *q0 = create_new_state("q0", FSM_FALSE, "FSM_2", fsm);
|
||||||
|
state_t *q1 = create_new_state("q1", FSM_FALSE, "FSM_2", fsm);
|
||||||
|
state_t *q2 = create_new_state("q2", FSM_FALSE, "FSM_2", fsm);
|
||||||
|
state_t *q3 = create_new_state("q3", FSM_TRUE, "FSM_2", fsm);
|
||||||
|
state_t *q4 = create_new_state("q4", FSM_TRUE, "FSM_2", fsm);
|
||||||
|
|
||||||
|
fsm->states[0] = q0;
|
||||||
|
fsm->states[1] = q1;
|
||||||
|
fsm->states[2] = q2;
|
||||||
|
fsm->states[3] = q3;
|
||||||
|
fsm->states[4] = q4;
|
||||||
|
|
||||||
|
set_fsm_initial_state(fsm, q0);
|
||||||
|
|
||||||
|
tt_t *trans_table = NULL;
|
||||||
|
//State q0
|
||||||
|
trans_table = &(q0->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "0", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "1", 1, q2);
|
||||||
|
|
||||||
|
//State q1
|
||||||
|
trans_table = &(q1->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "0", 1, q3);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "1", 1, q2);
|
||||||
|
|
||||||
|
//State q2
|
||||||
|
trans_table = &(q2->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "0", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "1", 1, q4);
|
||||||
|
|
||||||
|
//State q3
|
||||||
|
trans_table = &(q3->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "0", 1, q3);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "1", 1, q2);
|
||||||
|
|
||||||
|
//State q4
|
||||||
|
trans_table = &(q4->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "0", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "1", 1, q4);
|
||||||
|
|
||||||
|
return fsm;
|
||||||
|
}
|
||||||
|
|
||||||
|
fsm_t *
|
||||||
|
fsm_odd_1(){
|
||||||
|
|
||||||
|
fsm_t *fsm = create_new_fsm("FSM_3", "0,1",2);
|
||||||
|
|
||||||
|
state_t *q0 = create_new_state("q0", FSM_FALSE, "FSM_3", fsm);
|
||||||
|
state_t *q1 = create_new_state("q1", FSM_TRUE, "FSM_3", fsm);
|
||||||
|
|
||||||
|
fsm->states[0] = q0;
|
||||||
|
fsm->states[1] = q1;
|
||||||
|
|
||||||
|
set_fsm_initial_state(fsm, q0);
|
||||||
|
|
||||||
|
tt_t *trans_table = NULL;
|
||||||
|
//State q0
|
||||||
|
trans_table = &(q0->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "0", 1, q0);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "1", 1, q1);
|
||||||
|
|
||||||
|
//State q1
|
||||||
|
trans_table = &(q1->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "0", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "1", 1, q0);
|
||||||
|
|
||||||
|
return fsm;
|
||||||
|
}
|
||||||
|
|
||||||
|
fsm_t *
|
||||||
|
fsm_balanced_paranthesis_3_levels(){
|
||||||
|
fsm_t *fsm = create_new_fsm("FSM_4", "(,)",2);
|
||||||
|
|
||||||
|
|
||||||
|
state_t *q0 = create_new_state("q0", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q1 = create_new_state("q1", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q2 = create_new_state("q2", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q3 = create_new_state("q3", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q4 = create_new_state("q4", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q5 = create_new_state("q5", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q6 = create_new_state("q6", FSM_TRUE, "FSM_4", fsm);
|
||||||
|
state_t *q7 = create_new_state("q7", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q8 = create_new_state("q8", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q9 = create_new_state("q9", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q10 = create_new_state("q10", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q11 = create_new_state("q11", FSM_TRUE, "FSM_4", fsm);
|
||||||
|
state_t *q12 = create_new_state("q12", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q13 = create_new_state("q13", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q14 = create_new_state("q14", FSM_TRUE, "FSM_4", fsm);
|
||||||
|
state_t *q15 = create_new_state("q15", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q16 = create_new_state("q16", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
state_t *q17 = create_new_state("q17", FSM_FALSE, "FSM_4", fsm);
|
||||||
|
|
||||||
|
set_fsm_initial_state(fsm, q0);
|
||||||
|
|
||||||
|
fsm->states[0] = q0;
|
||||||
|
fsm->states[1] = q1;
|
||||||
|
fsm->states[2] = q2;
|
||||||
|
fsm->states[3] = q3;
|
||||||
|
fsm->states[4] = q4;
|
||||||
|
fsm->states[5] = q5;
|
||||||
|
fsm->states[6] = q6;
|
||||||
|
fsm->states[7] = q7;
|
||||||
|
fsm->states[8] = q8;
|
||||||
|
fsm->states[9] = q9;
|
||||||
|
fsm->states[10] = q10;
|
||||||
|
fsm->states[11] = q11;
|
||||||
|
fsm->states[12] = q12;
|
||||||
|
fsm->states[13] = q13;
|
||||||
|
fsm->states[14] = q14;
|
||||||
|
fsm->states[15] = q15;
|
||||||
|
fsm->states[16] = q16;
|
||||||
|
fsm->states[17] = q17;
|
||||||
|
|
||||||
|
tt_t *trans_table = NULL;
|
||||||
|
|
||||||
|
//State q0 (initial state)
|
||||||
|
trans_table = &(q0->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q17);
|
||||||
|
|
||||||
|
//State q1
|
||||||
|
trans_table = &(q1->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q2);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q11);
|
||||||
|
|
||||||
|
//State q2
|
||||||
|
trans_table = &(q2->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q3);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q13);
|
||||||
|
|
||||||
|
//State q3
|
||||||
|
trans_table = &(q3->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q17);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q4);
|
||||||
|
|
||||||
|
//State q4
|
||||||
|
trans_table = &(q4->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q17);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q5);
|
||||||
|
|
||||||
|
//State q5
|
||||||
|
trans_table = &(q5->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q17);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q6);
|
||||||
|
|
||||||
|
//State q6
|
||||||
|
trans_table = &(q6->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q7);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q17);
|
||||||
|
|
||||||
|
//State q7
|
||||||
|
trans_table = &(q7->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q8);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q17);
|
||||||
|
|
||||||
|
//State q8
|
||||||
|
trans_table = &(q8->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q9);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q17);
|
||||||
|
|
||||||
|
//State q9
|
||||||
|
trans_table = &(q9->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q17);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q10);
|
||||||
|
|
||||||
|
//State q10
|
||||||
|
trans_table = &(q10->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q17);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q5);
|
||||||
|
|
||||||
|
//State q11
|
||||||
|
trans_table = &(q11->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q12);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q17);
|
||||||
|
|
||||||
|
//State q12
|
||||||
|
trans_table = &(q12->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q17);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q11);
|
||||||
|
|
||||||
|
//State q13
|
||||||
|
trans_table = &(q13->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q17);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q14);
|
||||||
|
|
||||||
|
//State q14
|
||||||
|
trans_table = &(q14->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q15);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q17);
|
||||||
|
|
||||||
|
//State q15
|
||||||
|
trans_table = &(q15->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q16);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q17);
|
||||||
|
|
||||||
|
//State q16
|
||||||
|
trans_table = &(q16->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q17);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q13);
|
||||||
|
|
||||||
|
//State q17
|
||||||
|
trans_table = &(q17->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "(", 1, q17);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, ")", 1, q17);
|
||||||
|
|
||||||
|
return fsm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fsm_t *
|
||||||
|
fsm_phone_validation_6_digits(){
|
||||||
|
|
||||||
|
fsm_t *fsm = create_new_fsm("FSM_5", "0,1,2,3,4,5,6,7,8,9",10);
|
||||||
|
|
||||||
|
state_t *q0 = create_new_state("q0", FSM_FALSE, "FSM_5", fsm);
|
||||||
|
state_t *q1 = create_new_state("q1", FSM_FALSE, "FSM_5", fsm);
|
||||||
|
state_t *q2 = create_new_state("q2", FSM_FALSE, "FSM_5", fsm);
|
||||||
|
state_t *q3 = create_new_state("q3", FSM_FALSE, "FSM_5", fsm);
|
||||||
|
state_t *q4 = create_new_state("q4", FSM_FALSE, "FSM_5", fsm);
|
||||||
|
state_t *q5 = create_new_state("q5", FSM_FALSE, "FSM_5", fsm);
|
||||||
|
state_t *q6 = create_new_state("q6", FSM_TRUE, "FSM_5", fsm);
|
||||||
|
state_t *q7 = create_new_state("q7", FSM_FALSE, "FSM_5", fsm); // Dead state
|
||||||
|
|
||||||
|
set_fsm_initial_state(fsm, q0);
|
||||||
|
|
||||||
|
fsm->states[0] = q0;
|
||||||
|
fsm->states[1] = q1;
|
||||||
|
fsm->states[2] = q2;
|
||||||
|
fsm->states[3] = q3;
|
||||||
|
fsm->states[4] = q4;
|
||||||
|
fsm->states[5] = q5;
|
||||||
|
fsm->states[6] = q6;
|
||||||
|
fsm->states[7] = q7;
|
||||||
|
|
||||||
|
tt_t *trans_table = NULL;
|
||||||
|
//State q0
|
||||||
|
trans_table = &(q0->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "0", 1, q7);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "1", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "2", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "3", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "4", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "5", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "6", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "7", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "8", 1, q1);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "9", 1, q1);
|
||||||
|
|
||||||
|
for(int i = 1 ; i <= 6 ; i++){
|
||||||
|
|
||||||
|
trans_table = &(fsm->states[i]->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "0", 1, fsm->states[i+1]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "1", 1, fsm->states[i+1]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "2", 1, fsm->states[i+1]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "3", 1, fsm->states[i+1]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "4", 1, fsm->states[i+1]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "5", 1, fsm->states[i+1]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "6", 1, fsm->states[i+1]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "7", 1, fsm->states[i+1]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "8", 1, fsm->states[i+1]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "9", 1, fsm->states[i+1]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
trans_table = &(fsm->states[7]->state_trans_table);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "0", 1, fsm->states[7]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "1", 1, fsm->states[7]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "2", 1, fsm->states[7]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "3", 1, fsm->states[7]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "4", 1, fsm->states[7]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "5", 1, fsm->states[7]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "6", 1, fsm->states[7]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "7", 1, fsm->states[7]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "8", 1, fsm->states[7]);
|
||||||
|
create_and_insert_new_tt_entry(trans_table, "9", 1, fsm->states[7]);
|
||||||
|
return fsm;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
|
||||||
|
|
||||||
|
fsm_t *fsm1 = fsm_end_with_strict_pattern_01_or_10();
|
||||||
|
print_fsm(fsm1);
|
||||||
|
|
||||||
|
fsm_t *fsm2 = fsm_end_with_00_or_11();
|
||||||
|
print_fsm(fsm2);
|
||||||
|
|
||||||
|
fsm_t *fsm3 = fsm_odd_1();
|
||||||
|
print_fsm(fsm3);
|
||||||
|
|
||||||
|
fsm_t *fsm4 = fsm_balanced_paranthesis_3_levels();
|
||||||
|
print_fsm(fsm4);
|
||||||
|
|
||||||
|
fsm_t *fsm5 = fsm_phone_validation_6_digits();
|
||||||
|
print_fsm(fsm5);
|
||||||
|
|
||||||
|
/*FSM Algorithm execution*/
|
||||||
|
|
||||||
|
// fsm_bool_t fsm_result;
|
||||||
|
// fsm_error_t fsm_error;
|
||||||
|
|
||||||
|
// fsm_error = execute_fsm(fsm1,
|
||||||
|
// "00",
|
||||||
|
// strlen("00"),
|
||||||
|
// &fsm_result);
|
||||||
|
|
||||||
|
// if(fsm_error == FSM_NO_ERROR ){
|
||||||
|
// if( fsm_result == FSM_TRUE ){
|
||||||
|
// printf("Input String is Validated\n");
|
||||||
|
// }
|
||||||
|
// else{
|
||||||
|
// printf("Input String is not Valid\n");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
/***Constants***/
|
/***Constants***/
|
||||||
|
|
||||||
|
|
||||||
|
#define space " " // 4 ws
|
||||||
|
|
||||||
#define MAX_INP_BUFFER_LEN 128
|
#define MAX_INP_BUFFER_LEN 128
|
||||||
#define MAX_TRANSITION_TABLE_SIZE 128
|
#define MAX_TRANSITION_TABLE_SIZE 128
|
||||||
#define MAX_STATE_NAME_SIZE 32
|
#define MAX_STATE_NAME_SIZE 32
|
||||||
@@ -11,6 +14,7 @@
|
|||||||
#define MAX_TRANSITION_KEY_SIZE 64
|
#define MAX_TRANSITION_KEY_SIZE 64
|
||||||
#define MAX_ALP_BUFFER_SIZE 30
|
#define MAX_ALP_BUFFER_SIZE 30
|
||||||
#define MAX_FINAL_STATE 128
|
#define MAX_FINAL_STATE 128
|
||||||
|
#define MAX_NUM_OF_STATES 128
|
||||||
|
|
||||||
|
|
||||||
/***Data structures and custom datatypes***/
|
/***Data structures and custom datatypes***/
|
||||||
@@ -28,6 +32,13 @@ typedef enum{
|
|||||||
|
|
||||||
}fsm_bool_t;
|
}fsm_bool_t;
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
|
||||||
|
FSM_NO_TRANSITION,
|
||||||
|
FSM_NO_ERROR
|
||||||
|
|
||||||
|
}fsm_error_t;
|
||||||
|
|
||||||
|
|
||||||
/*This data structure act similar
|
/*This data structure act similar
|
||||||
* to the behaviour of transition
|
* to the behaviour of transition
|
||||||
@@ -73,12 +84,18 @@ struct fsm_{
|
|||||||
/*Initial state of FSM to start with*/
|
/*Initial state of FSM to start with*/
|
||||||
state_t *initial_state;
|
state_t *initial_state;
|
||||||
|
|
||||||
|
/*Number of States*/
|
||||||
|
state_t *states[MAX_NUM_OF_STATES];
|
||||||
|
|
||||||
/*Number of states in FSM*/
|
/*Number of states in FSM*/
|
||||||
unsigned int state_count;
|
unsigned int state_count;
|
||||||
|
|
||||||
/*Set of alphabet*/
|
/*Set of alphabet*/
|
||||||
char alphabet[MAX_ALP_BUFFER_SIZE];
|
char alphabet[MAX_ALP_BUFFER_SIZE];
|
||||||
|
|
||||||
|
/*Count of No. of alphabets*/
|
||||||
|
unsigned int alphabet_count;
|
||||||
|
|
||||||
/*Set of final/accept states*/
|
/*Set of final/accept states*/
|
||||||
char final_states[MAX_FINAL_STATE];
|
char final_states[MAX_FINAL_STATE];
|
||||||
|
|
||||||
@@ -101,7 +118,7 @@ struct fsm_{
|
|||||||
/***Function Prototypes***/
|
/***Function Prototypes***/
|
||||||
|
|
||||||
fsm_t*
|
fsm_t*
|
||||||
create_new_fsm(const char *fsm_name, const char *inp_alpha);
|
create_new_fsm(const char *fsm_name, const char *inp_alpha, unsigned int alpha_count);
|
||||||
|
|
||||||
state_t*
|
state_t*
|
||||||
create_new_state(const char *state_name,
|
create_new_state(const char *state_name,
|
||||||
@@ -122,6 +139,16 @@ create_and_insert_new_tt_entry(tt_t *trans_table,
|
|||||||
tt_entry_t*
|
tt_entry_t*
|
||||||
get_next_empty_tt_entry(tt_t *trans_table);
|
get_next_empty_tt_entry(tt_t *trans_table);
|
||||||
|
|
||||||
|
fsm_error_t
|
||||||
|
execute_fsm(fsm_t *fsm,
|
||||||
|
char *input_buffer,
|
||||||
|
unsigned int size,
|
||||||
|
fsm_bool_t *fsm_result);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
print_fsm(fsm_t *fsm);
|
||||||
|
|
||||||
/**static(hidden) functions***/
|
/**static(hidden) functions***/
|
||||||
static inline fsm_bool_t
|
static inline fsm_bool_t
|
||||||
is_tt_entry_empty(tt_entry_t *tt_entry){
|
is_tt_entry_empty(tt_entry_t *tt_entry){
|
||||||
|
|||||||
216
src/fsm.c
216
src/fsm.c
@@ -5,7 +5,7 @@
|
|||||||
#include "fsm.h"
|
#include "fsm.h"
|
||||||
|
|
||||||
fsm_t *
|
fsm_t *
|
||||||
create_new_fsm(const char* fsm_name, const char *inp_alpha)
|
create_new_fsm(const char* fsm_name, const char *inp_alpha, unsigned int alpha_count)
|
||||||
{
|
{
|
||||||
|
|
||||||
fsm_t *fsm = calloc(1, sizeof(fsm_t));
|
fsm_t *fsm = calloc(1, sizeof(fsm_t));
|
||||||
@@ -20,6 +20,8 @@ create_new_fsm(const char* fsm_name, const char *inp_alpha)
|
|||||||
memset(fsm->input_buffer, 0, 1);
|
memset(fsm->input_buffer, 0, 1);
|
||||||
fsm->input_buffer_cursor = 0;
|
fsm->input_buffer_cursor = 0;
|
||||||
fsm->input_buffer_size = 0;
|
fsm->input_buffer_size = 0;
|
||||||
|
fsm->alphabet_count = alpha_count;
|
||||||
|
|
||||||
return fsm;
|
return fsm;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -113,4 +115,216 @@ create_and_insert_new_tt_entry(tt_t *trans_table,
|
|||||||
tt_entry_ptr->next_state = next_state;
|
tt_entry_ptr->next_state = next_state;
|
||||||
|
|
||||||
return tt_entry_ptr;
|
return tt_entry_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static state_t *
|
||||||
|
transition(state_t *curr_state, char *input_buffer, unsigned int *inp_ptr){
|
||||||
|
|
||||||
|
assert(curr_state); // To check if curr_state is not NULL.
|
||||||
|
assert(input_buffer); // To check input_buffer is not NULL.
|
||||||
|
|
||||||
|
unsigned int rem_len_inp_buf = strlen(input_buffer);
|
||||||
|
|
||||||
|
tt_t *trans_table = &(curr_state->state_trans_table);
|
||||||
|
|
||||||
|
tt_entry_t *entry_ptr = NULL;
|
||||||
|
|
||||||
|
state_t *next_state = NULL;
|
||||||
|
FSM_ITERATE_TRANS_TABLE_BEGIN( trans_table, entry_ptr ){
|
||||||
|
if( entry_ptr->transition_key_size <= rem_len_inp_buf &&
|
||||||
|
strncmp(entry_ptr->transition_key,
|
||||||
|
input_buffer + *inp_ptr,
|
||||||
|
entry_ptr->transition_key_size) == 0 &&
|
||||||
|
is_tt_entry_empty(entry_ptr) == FSM_FALSE ){
|
||||||
|
|
||||||
|
next_state = entry_ptr->next_state;
|
||||||
|
*inp_ptr += entry_ptr->transition_key_size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}FSM_ITERATE_TRANS_TABLE_END( trans_table, entry_ptr)
|
||||||
|
|
||||||
|
return next_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fsm_error_t
|
||||||
|
execute_fsm(fsm_t *fsm,
|
||||||
|
char *input_buffer,
|
||||||
|
unsigned int size,
|
||||||
|
fsm_bool_t *fsm_result){
|
||||||
|
|
||||||
|
fsm_error_t algo_output = FSM_NO_ERROR;
|
||||||
|
|
||||||
|
char *buffer_to_parse;
|
||||||
|
unsigned int input_buffer_len = 0; // length of input buffer being used
|
||||||
|
fsm->input_buffer_cursor = 0;
|
||||||
|
|
||||||
|
state_t *curr_state = NULL; /*Pointer to the current state
|
||||||
|
of given FSM*/
|
||||||
|
curr_state = fsm->initial_state;
|
||||||
|
|
||||||
|
state_t *next_state = NULL;
|
||||||
|
|
||||||
|
/*FSM has a problem.
|
||||||
|
It don't has any initial
|
||||||
|
state.*/
|
||||||
|
|
||||||
|
if( curr_state == NULL ){
|
||||||
|
printf("FSM is not programmed correctly.\n \
|
||||||
|
FSM don't have an initial state.\n");
|
||||||
|
algo_output = FSM_NO_TRANSITION;
|
||||||
|
|
||||||
|
return algo_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Use buffer sent by applicaton*/
|
||||||
|
if( input_buffer && size > 0 ){
|
||||||
|
buffer_to_parse = input_buffer;
|
||||||
|
input_buffer_len = size;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
/*Use buffer set to fsm by application*/
|
||||||
|
buffer_to_parse = fsm->input_buffer;
|
||||||
|
input_buffer_len = fsm->input_buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( input_buffer_len != strlen(buffer_to_parse) ){
|
||||||
|
|
||||||
|
printf("Size of input buffer given and actual size of input buffer is different\n");
|
||||||
|
|
||||||
|
algo_output = FSM_NO_TRANSITION;
|
||||||
|
return algo_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( fsm->input_buffer_cursor < input_buffer_len ){
|
||||||
|
|
||||||
|
next_state = transition(curr_state, buffer_to_parse, &fsm->input_buffer_cursor); // Transition function
|
||||||
|
// to get to next state
|
||||||
|
// for current input
|
||||||
|
// symbol if it exist.
|
||||||
|
|
||||||
|
if( next_state == NULL ){
|
||||||
|
printf("Somthing went wrong!!\n \
|
||||||
|
The next state for the current state (%s) and remaining input \
|
||||||
|
string (%s) with current input pointer at (%u) is NULL\n \
|
||||||
|
This means either there is no transition for the current input \
|
||||||
|
symbol or the next state for the current input symbol is NULL\n \
|
||||||
|
For both case, the FSM is programmed not correctly.\n", curr_state->state_name,
|
||||||
|
buffer_to_parse + fsm->input_buffer_cursor,
|
||||||
|
fsm->input_buffer_cursor);
|
||||||
|
|
||||||
|
algo_output = FSM_NO_TRANSITION;
|
||||||
|
return algo_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
//update...
|
||||||
|
curr_state = next_state;
|
||||||
|
next_state = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Now, the input buffer is processed without any issue.
|
||||||
|
//Therefore, there is no transition error.
|
||||||
|
|
||||||
|
algo_output = FSM_NO_ERROR;
|
||||||
|
//Checking if the curr_state is accept state or not.
|
||||||
|
|
||||||
|
if( curr_state->is_final == FSM_TRUE){
|
||||||
|
*fsm_result = FSM_TRUE;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
*fsm_result = FSM_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return algo_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
print_fsm(fsm_t *fsm){
|
||||||
|
|
||||||
|
char state[6];
|
||||||
|
char input[fsm->alphabet_count][6];
|
||||||
|
char next_state[fsm->alphabet_count + 1][6];
|
||||||
|
|
||||||
|
memset(state, '\0', sizeof state);
|
||||||
|
for(unsigned int i = 0 ; i < fsm->alphabet_count ; i++ ){
|
||||||
|
memset(input[i], '\0', sizeof input[i]);
|
||||||
|
memset(next_state[i], '\0', sizeof next_state[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char alpha[strlen(fsm->alphabet)+1];
|
||||||
|
memset(alpha , 0, strlen(fsm->alphabet)+1);
|
||||||
|
strncpy(alpha, fsm->alphabet, strlen(fsm->alphabet)+1);
|
||||||
|
int i = 0;
|
||||||
|
char *ch = NULL;
|
||||||
|
ch = strtok(alpha, ",");
|
||||||
|
do{
|
||||||
|
strncpy(input[i++],ch,strlen(ch));
|
||||||
|
}while( (ch = strtok(NULL, ",")) );
|
||||||
|
|
||||||
|
printf("FSM name : %s\n", fsm->fsm_name);
|
||||||
|
printf("Alphabets : %s\n", fsm->alphabet);
|
||||||
|
printf("States : ");
|
||||||
|
for(unsigned int i = 0 ; i < fsm->state_count ; i++ ){
|
||||||
|
sprintf(state,"q%d",i);
|
||||||
|
printf("%s", state);
|
||||||
|
|
||||||
|
if( i < fsm->state_count - 1 )
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
printf("Initial State : %s\n", fsm->initial_state->state_name);
|
||||||
|
printf("Final States : %s\n", fsm->final_states);
|
||||||
|
|
||||||
|
printf("Transition Table :\n");
|
||||||
|
|
||||||
|
//Header line
|
||||||
|
printf(" "space"|");
|
||||||
|
for(unsigned int i = 0 ; i < fsm->alphabet_count ; i++ ){
|
||||||
|
printf(space"%5s",input[i]);
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
printf("--------------");
|
||||||
|
for(unsigned int i = 0 ; i < fsm->alphabet_count ; i++ )
|
||||||
|
printf("---------");
|
||||||
|
printf("---------\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
tt_t *table_ptr = NULL;
|
||||||
|
tt_entry_t *entry_ptr = NULL;
|
||||||
|
for( unsigned int i = 0 ; i < fsm->state_count ; i++ ){
|
||||||
|
|
||||||
|
strncpy(next_state[0], fsm->states[i]->state_name,
|
||||||
|
strlen(fsm->states[i]->state_name));
|
||||||
|
|
||||||
|
table_ptr = &(fsm->states[i]->state_trans_table);
|
||||||
|
FSM_ITERATE_TRANS_TABLE_BEGIN(table_ptr, entry_ptr){
|
||||||
|
|
||||||
|
if( is_tt_entry_empty(entry_ptr) == FSM_FALSE ){
|
||||||
|
for(unsigned int j = 0 ; j < fsm->alphabet_count ; j++ ){
|
||||||
|
if( strncmp(entry_ptr->transition_key, input[j],
|
||||||
|
entry_ptr->transition_key_size) == 0){
|
||||||
|
|
||||||
|
strncpy(next_state[j+1], entry_ptr->next_state->state_name,
|
||||||
|
strlen(entry_ptr->next_state->state_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}FSM_ITERATE_TRANS_TABLE_END(table_ptr, entry_ptr)
|
||||||
|
|
||||||
|
printf(space"%5s"space"|", next_state[0]);
|
||||||
|
memset(next_state[0], '\0', sizeof state[0]);
|
||||||
|
for(unsigned int k = 0 ; k < fsm->alphabet_count ; k++ ){
|
||||||
|
printf(space"%5s", next_state[k+1]);
|
||||||
|
memset(next_state[k+1], '\0', sizeof next_state[k+1]);
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user