The fsm
section is the main section of the grammar description file. Its
purpose is to describe all the states and transitions together with their input events
and guards. It also defines which executable actions are to be invoked on each
transition between states. From this list of grammar rules, the parser
generator program creates an executable finite state machine that is capable of recognising
the specified input events or tokens that cause state transitions away from each
state, and capable of generating errors as soon as an unrecognised input event
occurs for a given state.
Here is an example of part of a simple state machine grammar, which when
parsed by a
parser generator creates a state machine that controls a traffic light protected
pedestrian crossing. Notice how the grammar section begins with the keyword
fsm
,
and that the keyword is followed by the name of the starting state in the
state machine, in this case 'Green
'.
Following the fsm
keyword and its starting state argument, the whole
body of the state machine description is contained between curly braces.
options
{
// assembly references, etc. in here ...
}
events
{
TIMERTICK,
BUTTONPRESS
}
guards
{
ButtonWasPressed
}
fsm(Green)
{
// The AllRed state is used when both traffic and
// pedestrians are barred from crossing. This is
// the state the controller is in while waiting
// for slower pedestrians to complete their crossing.
AllRed:
TIMERTICK RedAndYellow
{ SetLightRedAndYellow(); SetRedAndYellowTimer(); }
| BUTTONPRESS AllRed
{ RecordButtonPressed(); }
;
// This is an English traffic light! In England
// the lights go to both red and yellow lit up
// for a few seconds between being red and green.
RedAndYellow:
TIMERTICK TimedGreen
{ SetLightGreen(); SetGreenTimer(); }
| BUTTONPRESS RedAndYellow
{ RecordButtonPressed(); }
;
// Once the lights have gone green, there is a
// minimum interval they must remain green before
// the controller will respond to the next button press.
TimedGreen:
TIMERTICK[ButtonWasPressed] Yellow
{ SetLightYellow(); SetYellowTimer(); }
| BUTTONPRESS TimedGreen
{ RecordButtonPressed(); }
| TIMERTICK[!ButtonWasPressed] Green
;
// After the minimum interval for the lights on green
// has expired, the lights will stay on green indefinitely
// unless a pedestrian presses the request to cross button.
Green:
BUTTONPRESS Yellow
{ SetLightYellow(); RecordButtonPressed(); SetYellowTimer(); }
;
// The yellow light is displayed for a few seconds between
// green and red to tell traffic to stop at the light if
// it is safe for them to do so.
Yellow:
BUTTONPRESS Yellow
{ RecordButtonPressed(); }
| TIMERTICK RedWalk
{
SetLightRed(); SetLightWalk();
ClearButtonPress(); SetWalkTimer();
}
;
// Once the lights have gone to red, we allow
// pedestrians to cross the road.
RedWalk:
BUTTONPRESS RedWalk
| TIMERTICK AllRed
{ SetLightDontWalk(); SetAllRedTimer(); }
;
}