Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members  

executable_streamable_dfa.hh

00001 /*
00002 *  Name:      executable_streamable_dfa.hh
00003 *  Author:    Rafael Jesus Alcantara Perez
00004 *  Summary:   Executable Streamable Deterministic Finite Automaton
00005 *  Date:      $Date: 2003/10/06 12:45:11 $
00006 *  Revision:  $Revision: 1.2 $
00007 *
00008 *  Copyright (C) 1999-2002  Rafael Jesus Alcantara Perez <rafa@dedalo-ing.com>
00009 *
00010 *  This program is free software; you can redistribute it and/or modify
00011 *  it under the terms of the GNU General Public License as published by
00012 *  the Free Software Foundation; either version 2 of the License, or
00013 *  (at your option) any later version.
00014 *
00015 *  This program is distributed in the hope that it will be useful,
00016 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 *  GNU General Public License for more details.
00019 *
00020 *  You should have received a copy of the GNU General Public License
00021 *  along with this program; if not, write to the Free Software
00022 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00023 *  MA 02111-1307, USA.
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         //  C O N S T R U C T O R S
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         //  C O N S T R U C T O R S
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         //  S E L E C T O R S
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     };  // class TExecutableStreamableDfa
00161 
00162   }  // namespace automaton
00163 
00164 }  // namespace mpcl
00165 
00166 
00167 //
00168 //  C O N S T R U C T O R S
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   //  DFAML document must be validated, so parsing
00178   //  doesn't have to worry about syntax errors.
00179   //  First it musts find DFAML tag, and then skip
00180   //  it.
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 }  // read()
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   //  Reads ACTLIST tag/DECLARE end-tag.
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 }  // readActionList()
00258 
00259 
00260 //
00261 //  S E L E C T O R S
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   //  Writes ACTLIST beginning tag.
00275   //
00276   rtTARGET_OSTREAM << "  <actlist>\n";
00277 
00278   //
00279   //  Iterates over string to state map.
00280   //
00281   for (; ( I != tStringToStateMap.end() ) ;++I)
00282   {
00283     //
00284     //  Writes STATE beginning tag.
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 }  // writeActionList()
00305 
00306 
00307 #endif  // not _MPCL_AUTOMATON_EXECUTABLE_STREAMABLE_DFA__

Generated on Mon Oct 13 02:35:23 2003 for MPCL by doxygen1.2.18