FSM Guards - RopleyIT/GLRParser GitHub Wiki
The guards or conditions section of the FSM input grammar is optional. It is
identified by either the keyword guards
or conditions
followed by the comma-separated list of guard function names enclosed in curly
braces. When the input description is describing a state machine, the transitions between
states are caused by events that can be accompanied by a guard condition. Only
if the event occurs and the guard condition is true will the transition be made.
Guard conditions can be placed on events in
the input grammar, by placing the guard condition in square brackets. For in-line
state machines, note that every guard condition listed in the guards
section
must have a corresponding guard testing function within the part of the parser
class that you will write. For offline state machines, you may provide guard
functions in this way too, if you wish. However it is also possible to write the
guard function code into the grammar description if your state machine will be built
offline from auto-generated source code. This is discussed later in this page. If your grammar's options
section had
the namespace
set to MyApplication
and the
fsmclass
to MyFSM
, this means you have to write a
method with the correct guard function signature and name within the class
MyApplication.MyFSM
.
Each guard functon must be public, must return a boolean, and must take no
arguments. Any variables that the guard function needs access to in order to
determine whether to return false
or true
must be
accessible from the context of the FSM class within which the guard function is
written.
An example of a guards section containing the names of four guard-evaluating methods from your parser:
guards
{
IsFriendly,
EatsHumans,
Asleep,
Alive
}
An example of the parser class that provides these four method implementations:
namespace MyApplication
{
public partial class MyFSM
{
... other things ...
public bool IsFriendly()
{
return !someAnimalOfInterest.EatsHumans();
}
... the other three guard methods ...
}
}
When your grammar is going to be converted into source code for a state machine using the
ParseLR.exe
application, you also have the option of writing the guard
function code embedded in the grammar description. To do this, a number of points
should be noted:
- The code for the body of each guard method should immediately follow the name
of the guard function in the
guards
orconditions
section; - The code for the body of each guard method should be enclosed in curly braces;
- The context within which the code is written is the context of the FSM class itself, meaning that the code has access to private members of the FSM class if needed;
- The code block should return a boolean result for all possible paths through the code block.
Here is an example showing the IsFriendly
guard function from
the example above, rewritten as an inline guard function. The remaining three
guard functions are written manually into the parser class in the way described
above:
guards
{
IsFriendly
{
return !someAnimalOfInterest.EatsHumans();
},
EatsHumans,
Asleep,
Alive
}
Interestingly this guard function makes a call on one
of the other guards as part of its guard logic. Another
way this might have been done would have been to apply
the logical not operator where the guard condition is applied
to a token in the grammar, i.e. to use [!EatsHumans]
rather than IsFriendly
.