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>