Continue experimenting with state machines

This commit is contained in:
Abdelrahman Said 2023-06-13 23:36:14 +01:00
parent 23a7874950
commit 82c2fcdc64
2 changed files with 109 additions and 0 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
*.dSYM
fsm
fsm2

108
fsm2.c Normal file
View File

@ -0,0 +1,108 @@
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define ARR_LEN(X) (sizeof(X) / sizeof(X[0]))
typedef enum {
STATE_START,
STATE_INVALID,
STATE_OBJ,
STATE_ARR,
STATE_END,
} states;
states handle_start(char input);
states handle_obj(char input);
states handle_arr(char input);
states state_machine(states current, char input);
bool check_input(const char *text);
// clang-format off
const char *inputs[] = {
"{}",
"[]",
"{ }",
"[ ]",
" {}",
" []",
"{} ",
"[] ",
"{",
"[",
"}",
"]",
"{f}",
"[8]",
};
// clang-format on
int main(int argc, char *argv[]) {
for (int i = 0; i < ARR_LEN(inputs); ++i) {
printf("%20s is %s\n", inputs[i],
check_input(inputs[i]) ? "VALID" : "INVALID");
}
return EXIT_SUCCESS;
}
bool check_input(const char *text) {
states current = STATE_START;
for (const char *c = &(text[0]); *c != '\0'; ++c) {
current = state_machine(current, *c);
}
return current == STATE_END;
}
states handle_start(char input) {
if (isspace(input)) {
return STATE_START;
}
switch (input) {
case '{':
return STATE_OBJ;
case '[':
return STATE_ARR;
default:
return STATE_INVALID;
}
}
states handle_obj(char input) {
if (isspace(input)) {
return STATE_OBJ;
} else if (input == '}') {
return STATE_END;
}
return STATE_INVALID;
}
states handle_arr(char input) {
if (isspace(input)) {
return STATE_ARR;
} else if (input == ']') {
return STATE_END;
}
return STATE_INVALID;
}
states state_machine(states current, char input) {
switch (current) {
case STATE_START:
return handle_start(input);
case STATE_OBJ:
return handle_obj(input);
case STATE_ARR:
return handle_arr(input);
default:
return current;
}
}