genau - create C function from state machine description Options: ========= genau genau If the filename is omitted standard input is used. Input file format ================= The input file consists of several sections for options (options), state definitions (states), input definitions (inputs), output definitions (outputs) and transition rules (rules). The options section ------------------- The options section is started by a line containing only [options] Each line in the secion contains one option. Each option is a = pair. The keys and values can consist of several substrings. c file specifies the name of the *.c file to write containing the state machine transition function. h file specifies the name of the *.h file to write containing the constant definitions and function prototypes. prototypes specifies whether to use prototypes (yes, on, 1, true), K&R-style declarations (no, off, 0, false) or function headers based on dklibs-defined-constants (dk). transition function specifies the name of the state machines transition function. reset function specifies the name of the state machines reset function. reduced file specifies the name of the output file containing a reduced state machine description. reduce specifies (if no reduced file entry is present) whether to do a state-reduction or not. include protect specifies a name for the preprocessor constant used to prevent multiple header file inclusion. c define specifies a name for the preprocessor constant used to decide whether the functions are intern or extern. test file generates a C program to test all state/input combinations. doxygen comments controls whether or not to write comments for doxygen to output. squeezed controls whether to produce squeezed output (less spaces and empty lines) or normal output. The states section ------------------ The section is started by a [states] line. Each line contains one state name, optionally followed by a state number (type int). The inputs section ------------------ The section is started by a [inputs] line. Each line contains one input name, optionally followed by a number (type int). The outputs section ------------------- The section is started by a [outputs] line. Each line contains one output name, optionally followed by a number (type int). The rules section ----------------- The rules section is started by a [rules] line. Each line contains one transition rule consisting of - current state - input to process - next state - output. Each of the components is described by the name defined in the sections above. The wildcard symbol "*" can be used in the current state field and the input field. In this case the rule is valid for all states/inputs. If there are multiple rules valid for a given state/input combination priority is as follows: - An exact rule (containing no wildcards) has highest priority. - If there is no exact, the rule(s) containing on wildcard are candidates. If there is more than one such rule the one occuring _first_ in the file is choosen. - If no rule was found the general rule (both state and input given as wildcard) takes effect if available. - If there is no general rule given an implicit rule is used: The state machine remains in it's current state and issues the first output mentioned in the outputs section. Example ======= We will write a function checking whether a string is a valid C identifier (string started by character or underscore followed by characters, underscores and digits) or not. The check function is as follows: #include "testid.h" int check_string(char *str) { int state_machine; int input; int output; char *ptr; reset_decide(&state_machine); ptr = str; while(*ptr) { input = I_ANY; if(((*ptr) >= 'a') && ((*ptr) <= 'z')) input = I_CHARACTER; if(((*ptr) >= 'A') && ((*ptr) <= 'Z')) input = I_CHARACTER; if(((*ptr) >= '1') && ((*ptr) <= '9')) input = I_DIGIT; if((*ptr) == '0') input = I_DIGIT; if((*ptr) == '_') input = I_UNDERSCORE; (void)decide(&state_machine,input); ptr++; } output = decide(&state_machine,I_FINISHED); return output; } The automata description file is as follows: [options] c file = testid.c # C-file h file = testid.h # Header-file reduced file = testid2.au transition function = decide reset function = reset_decide [states] S_START # start state, adjusted by reset_decide S_OK # the string is an identifier S_ERROR # the string is not an identifier [inputs] I_ANY # any byte I_UNDERSCORE # an underscore I_CHARACTER # a character 'a'-'z' or 'A'-'Z' I_DIGIT # a digit I_FINISHED # end-of-string notification [outputs] O_OK # the string, as processed yet, is an identifier O_ERROR # the string, as processed yet, is not an identifier [rules] * * S_ERROR O_ERROR * I_FINISHED S_START O_ERROR S_START I_UNDERSCORE S_OK O_OK S_START I_CHARACTER S_OK O_OK S_OK I_UNDERSCORE S_OK O_OK S_OK I_CHARACTER S_OK O_OK S_OK I_DIGIT S_OK O_OK S_OK I_FINISHED S_START O_OK