diff --git a/.gitignore b/.gitignore index 5ea5ffa..67563dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.dSYM fsm fsm2 +fsm3 diff --git a/fsm3.c b/fsm3.c new file mode 100644 index 0000000..27c1786 --- /dev/null +++ b/fsm3.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include + +#define ARR_LEN(X) (sizeof(X) / sizeof(X[0])) + +typedef enum { + STATE_START, + STATE_INVALID, + STATE_KEY, + STATE_STRING, + STATE_KEY_END, + STATE_END, +} states; + +typedef states (*state_handler)(char input); + +states handle_start(char input); +states handle_key(char input); +states handle_string(char input); +states handle_key_end(char input); + +states state_machine(states current, char input); + +bool check_input(const char *text); + +// clang-format off +const char *inputs[] = { + "", + "{\"kjehu efhkwejhf wkehjf iyg\"}", + "{", + "}", + "{\"lkhefhkjhefhjjrj}", + "{jhejhuef hkwehj fwe}", + "{'wuy iygef'}", + "{\"hwekhewf'}", +}; +// clang-format on + +int main(int argc, char *argv[]) { + for (int i = 0; i < ARR_LEN(inputs); ++i) { + printf("%32s 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 state_machine(states current, char input) { + switch (current) { + case STATE_START: + return handle_start(input); + case STATE_KEY: + return handle_key(input); + case STATE_STRING: + return handle_string(input); + case STATE_KEY_END: + return handle_key_end(input); + case STATE_INVALID: + case STATE_END: + return current; + } +} + +states handle_start(char input) { + if (isspace(input)) { + return STATE_START; + } else if (input == '{') { + return STATE_KEY; + } + + return STATE_INVALID; +} + +states handle_key(char input) { + if (isspace(input)) { + return STATE_KEY; + } else if (input == '"') { + return STATE_STRING; + } + + return STATE_INVALID; +} + +states handle_string(char input) { + if (input == '"') { + return STATE_KEY_END; + } + + return STATE_STRING; +} + +states handle_key_end(char input) { + if (input == '}') { + return STATE_END; + } + + return STATE_INVALID; +}