• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
10 
11 #ifndef BOOST_MSM_FRONT_EUML_STT_GRAMMAR_H
12 #define BOOST_MSM_FRONT_EUML_STT_GRAMMAR_H
13 
14 #include <boost/msm/front/euml/common.hpp>
15 #include <boost/mpl/vector.hpp>
16 #include <boost/mpl/eval_if.hpp>
17 
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>
21 
22 namespace proto = boost::proto;
23 
24 namespace boost { namespace msm { namespace front { namespace euml
25 {
26 
27 template <class SOURCE,class EVENT,class TARGET,class ACTION=none,class GUARD=none>
28 struct TempRow
29 {
30     typedef SOURCE  Source;
31     typedef EVENT   Evt;
32     typedef TARGET  Target;
33     typedef ACTION  Action;
34     typedef GUARD   Guard;
35 };
36 
37 template <class TEMP_ROW>
38 struct convert_to_row
39 {
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;
42 };
43 template <class TEMP_ROW>
44 struct convert_to_internal_row
45 {
46     typedef Internal<typename TEMP_ROW::Evt,
47                      typename TEMP_ROW::Action,typename TEMP_ROW::Guard> type;
48 };
49 // explicit + fork + entry point + exit point grammar
50 struct BuildEntry
51     : proto::or_<
52         proto::when<
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>() >() >()
55         >
56     >
57 {};
58 
59 // row grammar
60 struct BuildNextStates
61    : proto::or_<
62         proto::when<
63                     proto::terminal<state_tag>,
64                     get_state_name<proto::_>()
65         >,
66         proto::when<
67                       BuildEntry,
68                       BuildEntry
69         >,
70         proto::when<
71                     proto::comma<BuildEntry,BuildEntry >,
72                     ::boost::mpl::push_back<
73                         make_vector_one_row<BuildEntry(proto::_left)>(),
74                         BuildEntry(proto::_right)>()
75         >,
76         proto::when <
77                     proto::comma<BuildNextStates,BuildEntry >,
78                     ::boost::mpl::push_back<
79                                 BuildNextStates(proto::_left),
80                                 BuildEntry(proto::_right) >()
81         >
82    >
83 {};
84 
85 template <class EventGuard,class ActionClass>
86 struct fusion_event_action_guard
87 {
88     typedef TempRow<none,typename EventGuard::Evt,none,typename ActionClass::Action,typename EventGuard::Guard> type;
89 };
90 
91 template <class SourceGuard,class ActionClass>
92 struct fusion_source_action_guard
93 {
94     typedef TempRow<typename SourceGuard::Source,none,none,typename ActionClass::Action,typename SourceGuard::Guard> type;
95 };
96 
97 template <class SourceClass,class EventClass>
98 struct fusion_source_event_action_guard
99 {
100     typedef TempRow<typename SourceClass::Source,typename EventClass::Evt,
101                     none,typename EventClass::Action,typename EventClass::Guard> type;
102 };
103 template <class Left,class Right>
104 struct fusion_left_right
105 {
106     typedef TempRow<typename Right::Source,typename Right::Evt,typename Left::Target
107                    ,typename Right::Action,typename Right::Guard> type;
108 };
109 
110 struct BuildEventPlusGuard
111     : proto::or_<
112         proto::when<
113             proto::subscript<proto::terminal<event_tag>, GuardGrammar >,
114             TempRow<none,proto::_left,none,none, GuardGrammar(proto::_right)>(proto::_right)
115         >
116     >
117  {};
118 
119 struct BuildSourceState
120    : proto::or_<
121         proto::when<
122                     proto::terminal<state_tag>,
123                     get_state_name<proto::_>()
124         >,
125         proto::when<
126                     BuildEntry,
127                     BuildEntry
128         >
129    >
130 {};
131 
132 struct BuildSourcePlusGuard
133     : proto::when<
134             proto::subscript<BuildSourceState,GuardGrammar >,
135             TempRow<BuildSourceState(proto::_left),none,none,none,GuardGrammar(proto::_right)>(proto::_right)
136         >
137 {};
138 
139 struct BuildEvent
140     : proto::or_<
141         // just event without guard/action
142          proto::when<
143                 proto::terminal<event_tag>,
144                 TempRow<none,proto::_,none>() >
145         // event / action
146        , proto::when<
147                 proto::divides<proto::terminal<event_tag>,ActionGrammar >,
148                 TempRow<none,proto::_left,none,ActionGrammar(proto::_right) >(proto::_right) >
149         // event [ guard ]
150        , proto::when<
151                 proto::subscript<proto::terminal<event_tag>,GuardGrammar >,
152                 TempRow<none,proto::_left,none,none,GuardGrammar(proto::_right)>(proto::_right) >
153         // event [ guard ] / action
154        , proto::when<
155                 proto::divides<BuildEventPlusGuard, ActionGrammar>,
156                 fusion_event_action_guard<BuildEventPlusGuard(proto::_left),
157                                           TempRow<none,none,none,ActionGrammar(proto::_right)>(proto::_right)
158                                            >()
159                 >
160         >
161 {};
162 struct BuildSource
163     : proto::or_<
164         // after == if just state without event or guard/action
165          proto::when<
166                 BuildSourceState,
167                 TempRow<BuildSourceState(proto::_),none,none>() >
168         // == source / action
169        , proto::when<
170                 proto::divides<BuildSourceState,ActionGrammar >,
171                 TempRow<BuildSourceState(proto::_left),none,none,ActionGrammar(proto::_right) >(proto::_right) >
172         // == source [ guard ]
173        , proto::when<
174                 proto::subscript<BuildSourceState,GuardGrammar >,
175                 TempRow<BuildSourceState(proto::_left),none,none,none,GuardGrammar(proto::_right)>(proto::_right) >
176         // == source [ guard ] / action
177        , proto::when<
178                 proto::divides<BuildSourcePlusGuard,
179                                ActionGrammar >,
180                 fusion_source_action_guard<BuildSourcePlusGuard(proto::_left),
181                                            TempRow<none,none,none,ActionGrammar(proto::_right)>(proto::_right)
182                                            >()
183                 >
184         >
185 {};
186 
187 struct BuildRight
188     : proto::or_<
189          proto::when<
190                 proto::plus<BuildSource,BuildEvent >,
191                 fusion_source_event_action_guard<BuildSource(proto::_left),BuildEvent(proto::_right)>()
192          >,
193          proto::when<
194                 BuildSource,
195                 BuildSource
196          >
197     >
198 {};
199 
200 struct BuildRow
201     : proto::or_<
202         // grammar 1
203         proto::when<
204             proto::equal_to<BuildNextStates,BuildRight >,
205             convert_to_row<
206                 fusion_left_right<TempRow<none,none,BuildNextStates(proto::_left)>,BuildRight(proto::_right)> >()
207         >,
208         // internal events
209         proto::when<
210             BuildRight,
211             convert_to_row<
212                 fusion_left_right<TempRow<none,none,none>,BuildRight(proto::_)> >()
213         >,
214         // grammar 2
215         proto::when<
216             proto::equal_to<BuildRight,BuildNextStates>,
217             convert_to_row<
218                 fusion_left_right<TempRow<none,none,BuildNextStates(proto::_right)>,BuildRight(proto::_left)> >()
219         >
220     >
221 {};
222 
223 // stt grammar
224 struct BuildStt
225    : proto::or_<
226         proto::when<
227                     proto::comma<BuildStt,BuildStt>,
228                     boost::mpl::push_back<BuildStt(proto::_left),BuildRow(proto::_right)>()
229                 >,
230         proto::when <
231                     BuildRow,
232                     make_vector_one_row<BuildRow(proto::_)>()
233         >
234    >
235 {};
236 
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
build_stt(Expr const &)242 build_stt(Expr const&)
243 {
244     return typename boost::result_of<BuildStt(Expr)>::type();
245 }
246 
247 // internal stt grammar
248 struct BuildInternalRow
249     :   proto::when<
250             BuildEvent,
251             convert_to_internal_row<
252                 fusion_left_right<TempRow<none,none,none>,BuildEvent(proto::_)> >()
253         >
254 {};
255 struct BuildInternalStt
256    : proto::or_<
257         proto::when<
258                     proto::comma<BuildInternalStt,BuildInternalStt>,
259                     boost::mpl::push_back<BuildInternalStt(proto::_left),BuildInternalRow(proto::_right)>()
260                 >,
261         proto::when <
262                     BuildInternalRow,
263                     make_vector_one_row<BuildInternalRow(proto::_)>()
264         >
265    >
266 {};
267 
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
build_internal_stt(Expr const &)273 build_internal_stt(Expr const&)
274 {
275     return typename boost::result_of<BuildInternalStt(Expr)>::type();
276 }
277 
278 
279 }}}}
280 #endif //BOOST_MSM_FRONT_EUML_STT_GRAMMAR_H
281