Test adding a number state machine
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | *.dSYM | ||||||
							
								
								
									
										20
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | { | ||||||
|  |     // Use IntelliSense to learn about possible attributes. | ||||||
|  |     // Hover to view descriptions of existing attributes. | ||||||
|  |     // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||||||
|  |     "version": "0.2.0", | ||||||
|  |     "configurations": [ | ||||||
|  |         { | ||||||
|  |             "name": "fsm", | ||||||
|  |             "type": "cppdbg", | ||||||
|  |             "request": "launch", | ||||||
|  |             "program": "${workspaceFolder}/fsm", | ||||||
|  |             "args": [], | ||||||
|  |             "stopAtEntry": false, | ||||||
|  |             "cwd": "${fileDirname}", | ||||||
|  |             "environment": [], | ||||||
|  |             "externalConsole": false, | ||||||
|  |             "MIMode": "lldb" | ||||||
|  |         } | ||||||
|  |     ] | ||||||
|  | } | ||||||
							
								
								
									
										167
									
								
								fsm.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								fsm.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | |||||||
|  | #include <ctype.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
|  | #define ARR_LEN(X) (sizeof(X) / sizeof(X[0])) | ||||||
|  |  | ||||||
|  | typedef enum { | ||||||
|  |   START_STATE, | ||||||
|  |   DECIMAL_STATE, | ||||||
|  |   NUM_STATE, | ||||||
|  |   FRACTION_STATE, | ||||||
|  |   EXPONENT_STATE, | ||||||
|  |   EXP_SIGN_STATE, | ||||||
|  |   POWER_STATE, | ||||||
|  |   END_STATE, | ||||||
|  |   INVALID_STATE, | ||||||
|  | } states; | ||||||
|  |  | ||||||
|  | states handle_start(char input); | ||||||
|  | states handle_decimal(char input); | ||||||
|  | states handle_num(char input); | ||||||
|  | states handle_fraction(char input); | ||||||
|  | states handle_exponent(char input); | ||||||
|  | states handle_exp_sign(char input); | ||||||
|  | states handle_power(char input); | ||||||
|  |  | ||||||
|  | states state_machine(states current, char input); | ||||||
|  |  | ||||||
|  | bool check_number(const char *num); | ||||||
|  |  | ||||||
|  | const char *inputs[] = { | ||||||
|  |     "0000000", // INVALID | ||||||
|  |     "01", // INVALID | ||||||
|  |     "f0", // INVALID | ||||||
|  |     "1f", // INVALID | ||||||
|  |     "1.f", // INVALID | ||||||
|  |     "1.0f", // INVALID | ||||||
|  |     "8987", // VALID | ||||||
|  |     "9.5", // VALID | ||||||
|  |     "    7", // VALID | ||||||
|  |     "  7.8", // VALID | ||||||
|  |     "732.9834e",   // INVALID | ||||||
|  |     "732.9834e-",  // INVALID | ||||||
|  |     "732.9834e+",  // INVALID | ||||||
|  |     "732.9834e-g", // INVALID | ||||||
|  |     "732.9834e-8", // VALID | ||||||
|  |     "732.9834e+8", // VALID | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | int main(int argc, char *argv[]) { | ||||||
|  |   for (int i = 0; i < ARR_LEN(inputs); ++i) { | ||||||
|  |     printf("%s is %s\n", inputs[i], | ||||||
|  |            check_number(inputs[i]) ? "VALID" : "INVALID"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return EXIT_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | states handle_start(char input) { | ||||||
|  |   if (isspace(input)) { | ||||||
|  |     return START_STATE; | ||||||
|  |   } else if (input == '0') { | ||||||
|  |     return DECIMAL_STATE; | ||||||
|  |   } else if (isdigit(input)) { | ||||||
|  |     return NUM_STATE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return INVALID_STATE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | states handle_decimal(char input) { | ||||||
|  |   if (input == '.') { | ||||||
|  |     return FRACTION_STATE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return INVALID_STATE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | states handle_num(char input) { | ||||||
|  |   if (isdigit(input)) { | ||||||
|  |     return NUM_STATE; | ||||||
|  |   } else if (input == '.') { | ||||||
|  |     return FRACTION_STATE; | ||||||
|  |   } else if (isspace(input)) { | ||||||
|  |     return END_STATE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return INVALID_STATE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | states handle_fraction(char input) { | ||||||
|  |   if (isdigit(input)) { | ||||||
|  |     return FRACTION_STATE; | ||||||
|  |   } else if (isspace(input)) { | ||||||
|  |     return END_STATE; | ||||||
|  |   } else if (input == 'e' || input == 'E') { | ||||||
|  |     return EXPONENT_STATE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return INVALID_STATE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | states handle_exponent(char input) { | ||||||
|  |   if (isdigit(input)) { | ||||||
|  |     return POWER_STATE; | ||||||
|  |   } else if (input == '+' || input == '-') { | ||||||
|  |     return EXP_SIGN_STATE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return INVALID_STATE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | states handle_exp_sign(char input) { | ||||||
|  |   if (isdigit(input)) { | ||||||
|  |     return POWER_STATE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return INVALID_STATE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | states handle_power(char input) { | ||||||
|  |   if (isdigit(input)) { | ||||||
|  |     return POWER_STATE; | ||||||
|  |   } else if (isspace(input)) { | ||||||
|  |     return END_STATE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return INVALID_STATE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | states state_machine(states current, char input) { | ||||||
|  |   switch (current) { | ||||||
|  |   case START_STATE: | ||||||
|  |     return handle_start(input); | ||||||
|  |   case DECIMAL_STATE: | ||||||
|  |     return handle_decimal(input); | ||||||
|  |   case NUM_STATE: | ||||||
|  |     return handle_num(input); | ||||||
|  |   case FRACTION_STATE: | ||||||
|  |     return handle_fraction(input); | ||||||
|  |   case EXPONENT_STATE: | ||||||
|  |     return handle_exponent(input); | ||||||
|  |   case EXP_SIGN_STATE: | ||||||
|  |     return handle_exp_sign(input); | ||||||
|  |   case POWER_STATE: | ||||||
|  |     return handle_power(input); | ||||||
|  |   case END_STATE: | ||||||
|  |   case INVALID_STATE: | ||||||
|  |     return current; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool check_number(const char *num) { | ||||||
|  |   states current = START_STATE; | ||||||
|  |  | ||||||
|  |   for (const char *c = &(num[0]); *c != '\0'; ++c) { | ||||||
|  |     current = state_machine(current, *c); | ||||||
|  |  | ||||||
|  |     if (current == INVALID_STATE) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return current == END_STATE || current == NUM_STATE || | ||||||
|  |          current == FRACTION_STATE || current == POWER_STATE; | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user