finite_state_machine - Support for building finite state machines
TABLE OF CONTENTS
SYNOPSIS
DESCRIPTION
DATA TYPES AND ROUTINES
EXAMPLE
COPYRIGHT
The finite_state.f90 source file defines a set of subroutines that allow you to build a so-called finite state machine. This is basically a way to structure a program or a part of a program that takes input (from a file or from some other source) and reacts to that input depending on the "state" it is in. A simple example could be a heating device with a thermostat: if the ambient temperature is high enough, there is no need to heat the room, so the system is in a rest state. If the temperature is lower than the set temperature, the heater should be turned on.
Finite state machines are encountered in many different areas in one form or other. Lexical analysers are another, more complicated example. When analysing an arithmetic expression like "1+2*3", the "+" that follows the "1" will probably bring the analyser in a different state: the literal number has terminated, it now needs to deal with an operator. This type of programming is used in the test/demo program to show how to use the finite_state.f90 source file to build a non-trivial FSM.
The source code expects a data type, STATE_DATA, that contains all information describing the finite state machine. The contents is entirely up to the application though. The state data are passed to the subroutine that implements the actual state machine, so that you can use this argument to prepare the computation.
The type must be defined in a module called "fsm_data_definitions":
module MYDATA_POOL type POOLDATA integer :: pool_index ! For private use by pool_acquire/pool_release real, dimension(100) :: work ! The actual work space end type include "mem_pool.f90" end module MYDATA_POOL |
subroutine machine( fsm, data, curstate ) use fsm_data_definitions implicit none type(FSM_STATE), intent(inout) :: fsm type(STATE_DATA), intent(inout) :: data character(len=*), intent(in) :: curstate end subroutine |
subroutine print_debug( lurep, data, oldstate, curstate ) use fsm_data_definitions implicit none integer, intent(in) :: lurep type(STATE_DATA), intent(inout) :: data character(len=*), intent(in) :: oldstate character(len=*), intent(in) :: curstate end subroutine |
subroutine print_debug( lurep, data, oldstate, curstate ) use fsm_data_definitions implicit none integer, intent(in) :: lurep type(STATE_DATA), intent(inout) :: data integer, intent(in) :: oldstate integer, intent(in) :: curstate end subroutine |
The use of the source code in the two files "finite_state.f90"and "fsm_state.f90" is illustrated by the following example:
module fsm_data_definitions implicit none include 'fsm_state.f90' type STATE_DATA integer :: position ! Current position in the string integer :: open_parens ! Number of open parentheses character(len=80) :: string ! String holding the expression end type STATE_DATA end module fsm_data_definitions |
The module that actually implements the finite state machine looks like this (the included file "finite_state.f90"contains the contains keyword):
module analyse_string use fsm_data_definitions include 'finite_state.f90' ! ! Here is the actual routine that implements the finite state machine ! ! analyse_expression -- ! Analyse an arithmetic expression ! Arguments: ! fsm Private data structure for the FSM machinery ! data Evaluation data structure ! state_name Current state of the machine ! subroutine analyse_expression( fsm, data, state_name ) type(FSM_STATE), intent(inout) :: fsm type(STATE_DATA), intent(inout) :: data character(len=*), intent(in) :: state_name ... end subroutine analyse_expression end module |
Copyright © 2006 Arjen Markus <arjenmarkus@sourceforge.net>