#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; }