1 // Copyright 2008 Christophe Henry
2 // henry UNDERSCORE christophe AT hotmail DOT com
3 // This is an extended version of the state machine available in the boost::mpl library
4 // Distributed under the same license as the original.
5 // Copyright for the original version:
6 // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
7 // under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_MSM_FRONT_EUML_STT_GRAMMAR_H
12 #define BOOST_MSM_FRONT_EUML_STT_GRAMMAR_H
14 #include <boost/msm/front/euml/common.hpp>
15 #include <boost/mpl/vector.hpp>
16 #include <boost/mpl/eval_if.hpp>
18 #include <boost/msm/front/euml/operator.hpp>
19 #include <boost/msm/front/euml/guard_grammar.hpp>
20 #include <boost/msm/front/euml/state_grammar.hpp>
22 namespace proto = boost::proto;
24 namespace boost { namespace msm { namespace front { namespace euml
27 template <class SOURCE,class EVENT,class TARGET,class ACTION=none,class GUARD=none>
30 typedef SOURCE Source;
32 typedef TARGET Target;
33 typedef ACTION Action;
37 template <class TEMP_ROW>
40 typedef Row<typename TEMP_ROW::Source,typename TEMP_ROW::Evt,typename TEMP_ROW::Target,
41 typename TEMP_ROW::Action,typename TEMP_ROW::Guard> type;
43 template <class TEMP_ROW>
44 struct convert_to_internal_row
46 typedef Internal<typename TEMP_ROW::Evt,
47 typename TEMP_ROW::Action,typename TEMP_ROW::Guard> type;
49 // explicit + fork + entry point + exit point grammar
53 proto::function<proto::terminal<proto::_>,proto::terminal<state_tag>,proto::terminal<state_tag> >,
54 get_fct<proto::_child_c<0>,get_state_name<proto::_child_c<1>() >(),get_state_name<proto::_child_c<2>() >() >()
60 struct BuildNextStates
63 proto::terminal<state_tag>,
64 get_state_name<proto::_>()
71 proto::comma<BuildEntry,BuildEntry >,
72 ::boost::mpl::push_back<
73 make_vector_one_row<BuildEntry(proto::_left)>(),
74 BuildEntry(proto::_right)>()
77 proto::comma<BuildNextStates,BuildEntry >,
78 ::boost::mpl::push_back<
79 BuildNextStates(proto::_left),
80 BuildEntry(proto::_right) >()
85 template <class EventGuard,class ActionClass>
86 struct fusion_event_action_guard
88 typedef TempRow<none,typename EventGuard::Evt,none,typename ActionClass::Action,typename EventGuard::Guard> type;
91 template <class SourceGuard,class ActionClass>
92 struct fusion_source_action_guard
94 typedef TempRow<typename SourceGuard::Source,none,none,typename ActionClass::Action,typename SourceGuard::Guard> type;
97 template <class SourceClass,class EventClass>
98 struct fusion_source_event_action_guard
100 typedef TempRow<typename SourceClass::Source,typename EventClass::Evt,
101 none,typename EventClass::Action,typename EventClass::Guard> type;
103 template <class Left,class Right>
104 struct fusion_left_right
106 typedef TempRow<typename Right::Source,typename Right::Evt,typename Left::Target
107 ,typename Right::Action,typename Right::Guard> type;
110 struct BuildEventPlusGuard
113 proto::subscript<proto::terminal<event_tag>, GuardGrammar >,
114 TempRow<none,proto::_left,none,none, GuardGrammar(proto::_right)>(proto::_right)
119 struct BuildSourceState
122 proto::terminal<state_tag>,
123 get_state_name<proto::_>()
132 struct BuildSourcePlusGuard
134 proto::subscript<BuildSourceState,GuardGrammar >,
135 TempRow<BuildSourceState(proto::_left),none,none,none,GuardGrammar(proto::_right)>(proto::_right)
141 // just event without guard/action
143 proto::terminal<event_tag>,
144 TempRow<none,proto::_,none>() >
147 proto::divides<proto::terminal<event_tag>,ActionGrammar >,
148 TempRow<none,proto::_left,none,ActionGrammar(proto::_right) >(proto::_right) >
151 proto::subscript<proto::terminal<event_tag>,GuardGrammar >,
152 TempRow<none,proto::_left,none,none,GuardGrammar(proto::_right)>(proto::_right) >
153 // event [ guard ] / action
155 proto::divides<BuildEventPlusGuard, ActionGrammar>,
156 fusion_event_action_guard<BuildEventPlusGuard(proto::_left),
157 TempRow<none,none,none,ActionGrammar(proto::_right)>(proto::_right)
164 // after == if just state without event or guard/action
167 TempRow<BuildSourceState(proto::_),none,none>() >
168 // == source / action
170 proto::divides<BuildSourceState,ActionGrammar >,
171 TempRow<BuildSourceState(proto::_left),none,none,ActionGrammar(proto::_right) >(proto::_right) >
172 // == source [ guard ]
174 proto::subscript<BuildSourceState,GuardGrammar >,
175 TempRow<BuildSourceState(proto::_left),none,none,none,GuardGrammar(proto::_right)>(proto::_right) >
176 // == source [ guard ] / action
178 proto::divides<BuildSourcePlusGuard,
180 fusion_source_action_guard<BuildSourcePlusGuard(proto::_left),
181 TempRow<none,none,none,ActionGrammar(proto::_right)>(proto::_right)
190 proto::plus<BuildSource,BuildEvent >,
191 fusion_source_event_action_guard<BuildSource(proto::_left),BuildEvent(proto::_right)>()
204 proto::equal_to<BuildNextStates,BuildRight >,
206 fusion_left_right<TempRow<none,none,BuildNextStates(proto::_left)>,BuildRight(proto::_right)> >()
212 fusion_left_right<TempRow<none,none,none>,BuildRight(proto::_)> >()
216 proto::equal_to<BuildRight,BuildNextStates>,
218 fusion_left_right<TempRow<none,none,BuildNextStates(proto::_right)>,BuildRight(proto::_left)> >()
227 proto::comma<BuildStt,BuildStt>,
228 boost::mpl::push_back<BuildStt(proto::_left),BuildRow(proto::_right)>()
232 make_vector_one_row<BuildRow(proto::_)>()
237 template <class Expr>
238 typename ::boost::mpl::eval_if<
239 typename proto::matches<Expr,BuildStt>::type,
240 boost::result_of<BuildStt(Expr)>,
241 make_invalid_type>::type
242 build_stt(Expr const&)
244 return typename boost::result_of<BuildStt(Expr)>::type();
247 // internal stt grammar
248 struct BuildInternalRow
251 convert_to_internal_row<
252 fusion_left_right<TempRow<none,none,none>,BuildEvent(proto::_)> >()
255 struct BuildInternalStt
258 proto::comma<BuildInternalStt,BuildInternalStt>,
259 boost::mpl::push_back<BuildInternalStt(proto::_left),BuildInternalRow(proto::_right)>()
263 make_vector_one_row<BuildInternalRow(proto::_)>()
268 template <class Expr>
269 typename ::boost::mpl::eval_if<
270 typename proto::matches<Expr,BuildInternalStt>::type,
271 boost::result_of<BuildInternalStt(Expr)>,
272 make_invalid_type>::type
273 build_internal_stt(Expr const&)
275 return typename boost::result_of<BuildInternalStt(Expr)>::type();
280 #endif //BOOST_MSM_FRONT_EUML_STT_GRAMMAR_H