00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _MPCL_AUTOMATON_EXECUTABLE_STREAMABLE_DFA__
00027 #define _MPCL_AUTOMATON_EXECUTABLE_STREAMABLE_DFA__
00028
00029 #include <iterator>
00030 #include "action_handler.hh"
00031 #include "defs.hh"
00032 #include "streamable_dfa.hh"
00033
00034
00036 namespace mpcl
00037 {
00038
00040 namespace automaton
00041 {
00042
00043 using text::regex::TMatcher;
00044
00054 template <typename TState, typename TEvent>
00055 class TExecutableStreamableDfa : public TStreamableDfa<TState, TEvent>
00056 {
00057
00058 public:
00059
00061 typedef
00062 typename TStreamableDfa<TState, TEvent>::char_type
00063 char_type;
00064
00066 typedef
00067 typename TStreamableDfa<TState, TEvent>::traits_type
00068 traits_type;
00069
00070
00071 protected:
00072
00074 typedef
00075 typename TStreamableDfa<TState, TEvent>::TStringToStateMap
00076 TStringToStateMap;
00077
00079 typedef
00080 typename TActionHandler<TState>::TActionNamesList
00081 TActionNamesList;
00082
00084 TActionHandler<TState>& rtActionHandler;
00085
00086
00087 public:
00088
00089
00090
00091
00092
00098 TExecutableStreamableDfa ( TEventHandler<TEvent>& rtSOURCE_BASE_EVENT_HANDLER ,
00099 TActionHandler<TState>& rtSOURCE_ACTION_HANDLER ) :
00100 TStreamableDfa<TState, TEvent> (rtSOURCE_BASE_EVENT_HANDLER) ,
00101 rtActionHandler (rtSOURCE_ACTION_HANDLER) {}
00102
00107 void move (const TState& rktSTATE)
00108 {
00109 TDeterministicFiniteAutomaton<TState, TEvent>::move (rktSTATE);
00110 if ( rtActionHandler.execute (rktSTATE) )
00111 {
00112 throw TIntegrityException ("action failed", __FILE__, __LINE__);
00113 }
00114 }
00115
00116
00117 protected:
00118
00119
00120
00121
00122
00127 void read (std::basic_istream<char_type, traits_type>& rtSOURCE_ISTREAM);
00128
00133 void readActionList (TMatcher& rtSOURCE_MATCHER);
00134
00135
00136 protected:
00137
00138
00139
00140
00141
00146 void write (std::basic_ostream<char_type, traits_type>& rtTARGET_OSTREAM) const
00147 {
00148 writeHeader (rtTARGET_OSTREAM);
00149 writeTransitionTable (rtTARGET_OSTREAM);
00150 writeActionList (rtTARGET_OSTREAM);
00151 writeFooter (rtTARGET_OSTREAM);
00152 }
00153
00158 void writeActionList (std::basic_ostream<char_type, traits_type>& rtTARGET_OSTREAM) const;
00159
00160 };
00161
00162 }
00163
00164 }
00165
00166
00167
00168
00169
00170
00171 template <typename TState, typename TEvent>
00172 inline void mpcl::automaton::TExecutableStreamableDfa<TState, TEvent>::
00173 read (std::basic_istream<char_type, traits_type>& rtSOURCE_ISTREAM)
00174 {
00175
00176
00177
00178
00179
00180
00181
00182 TMatcher tMatcher (rtSOURCE_ISTREAM);
00183
00184 tTransitionMap.clear();
00185 tMatcher.setCaseSensitiveness (false);
00186 readHeader (tMatcher);
00187 if ( !yPublic.empty() )
00188 {
00189 if ( ( yPublic != pkcDOCTYPE_VERSION_1_0 ) &&
00190 ( yPublic != pkcDOCTYPE_VERSION_2_0 ) )
00191 {
00192 throw TNotDfamlFileException ("this isn't a DFAML doctype");
00193 }
00194 }
00195 readTransitionTable (tMatcher);
00196 readActionList (tMatcher);
00197 readFooter (tMatcher);
00198 check();
00199
00200 }
00201
00202
00203 template <typename TState, typename TEvent>
00204 inline void mpcl::automaton::TExecutableStreamableDfa<TState, TEvent>::
00205 readActionList (TMatcher& rtSOURCE_MATCHER)
00206 {
00207
00208 # define DFA_REMOVE_COMMENTS(rtMATCHER) \
00209 { \
00210 while ( rtMATCHER.scan (pkcCommentTagPattern, NULL) ); \
00211 }
00212
00213 using text::Format;
00214
00215 typename TStringToStateMap::const_iterator I;
00216 TActionNamesList tActionNamesList;
00217 TString yActions;
00218 TString yStateName;
00219
00220
00221
00222
00223 if ( rtSOURCE_MATCHER.scan (pkcACTLIST_TagPattern, NULL) )
00224 {
00225 while (true)
00226 {
00227 DFA_REMOVE_COMMENTS (rtSOURCE_MATCHER);
00228 if ( !rtSOURCE_MATCHER.scan (pkcACTION_ElementPattern_1, &yStateName, &yActions, NULL) )
00229 {
00230 if ( !rtSOURCE_MATCHER.scan (pkcACTION_ElementPattern_2, &yActions, &yStateName, NULL) )
00231 {
00232 break;
00233 }
00234 }
00235 yStateName.lowercase();
00236 yActions.lowercase();
00237 I = tStringToStateMap.find (yStateName);
00238 if ( I == tStringToStateMap.end() )
00239 {
00240 TString yMessage;
00241
00242 yMessage = Format ("can't find state '%s'", yStateName.c_str());
00243 throw TNotFoundException (yMessage.c_str(), __FILE__, __LINE__);
00244 }
00245 tActionNamesList.clear();
00246 yActions.suppress (' ');
00247 yActions.split (',', std::back_insert_iterator<TActionNamesList> (tActionNamesList));
00248 rtActionHandler.setActions (I->second, tActionNamesList);
00249 }
00250 DFA_REMOVE_COMMENTS (rtSOURCE_MATCHER);
00251 rtSOURCE_MATCHER.scan (pkcACTLIST_EndTagPattern, NULL);
00252 DFA_REMOVE_COMMENTS (rtSOURCE_MATCHER);
00253 }
00254
00255 # undef DFA_REMOVE_COMMENTS
00256
00257 }
00258
00259
00260
00261
00262
00263
00264 template <typename TState, typename TEvent>
00265 inline void mpcl::automaton::TExecutableStreamableDfa<TState, TEvent>::
00266 writeActionList (std::basic_ostream<char_type, traits_type>& rtTARGET_OSTREAM) const
00267 {
00268
00269 typename TActionNamesList::const_iterator J;
00270 TActionNamesList tActionNamesList;
00271 typename TStringToStateMap::const_iterator I = tStringToStateMap.begin();
00272
00273
00274
00275
00276 rtTARGET_OSTREAM << " <actlist>\n";
00277
00278
00279
00280
00281 for (; ( I != tStringToStateMap.end() ) ;++I)
00282 {
00283
00284
00285
00286 tActionNamesList = rtActionHandler.getActions (I->second);
00287 rtTARGET_OSTREAM << " <action state=\""
00288 << I->first
00289 << "\" actions=\"";
00290 J = tActionNamesList.begin();
00291 if ( J != tActionNamesList.end() )
00292 {
00293 rtTARGET_OSTREAM << *J;
00294 ++J;
00295 for (; ( J != tActionNamesList.end() ) ;++J)
00296 {
00297 rtTARGET_OSTREAM << ", " << *J;
00298 }
00299 }
00300 rtTARGET_OSTREAM << "\">\n";
00301 }
00302 rtTARGET_OSTREAM << " </actlist>\n";
00303
00304 }
00305
00306
00307 #endif // not _MPCL_AUTOMATON_EXECUTABLE_STREAMABLE_DFA__