
genau - create C function from state machine description

Options:
=========

genau
genau <filename>

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

<key> = <value>

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

