Test adding a number state machine
This commit is contained in:
parent
7525036df2
commit
b9e3d5746a
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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user