Main Page | Class List | File List | Class Members | File Members

main.cpp

Go to the documentation of this file.
00001 
00005 //
00006 // Date:      20 August   2005   
00007 //
00008 // Copyright (c) Sergey Satskiy 2003 - 2005
00009 //               <sergesatsky@yahoo.com>
00010 //
00011 // Permission to copy, use, modify, sell and distribute this software 
00012 // is granted provided this copyright notice appears in all copies. 
00013 // This software is provided "as is" without express or implied
00014 // warranty, and with no claim as to its suitability for any purpose.
00015 //
00016 
00017 
00018 #include <iostream>
00019 #include <fstream>
00020 #include <string>
00021 #include <vector>
00022 using namespace std;
00023 
00024 #include <boost/algorithm/string/trim.hpp>
00025 using namespace boost;
00026 using namespace boost::algorithm;
00027 
00028 
00029 #include "fsm.h"
00030 using namespace FSM;
00031 
00032 #include "MachineGrammar.h"
00033 
00034 
00035 
00040 bool IsCinGood( void );
00041 bool IsCinGood( void )
00042 {
00043     if ( !cin.good() )
00044     {
00045         cin.clear();
00046         cin.ignore();
00047         cout << "Bad input." << endl;
00048         return false;
00049     }
00050     return true;
00051 }
00052 
00053 
00054 
00055 
00056 int  main( int  argc, char **  argv )
00057 {
00058     if ( argc > 2 )
00059     {
00060         cout << "Usage: " << argv[ 0 ] << " [MachineDescriptionFile]" << endl;
00061         return 1;
00062     }
00063 
00064     string      MachineFileName( "machine" );           // Default file name is 'machine'
00065     if ( argc == 2 )
00066     {
00067         MachineFileName = string( argv[ 1 ] );
00068     }
00069 
00070     ifstream    Description( MachineFileName.c_str() ); // Input file
00071     if ( !Description )
00072     {
00073         cout << "Cannot open '" << MachineFileName << "' file." << endl;
00074         return 2;
00075     }
00076     
00077 
00078     char                                    Buffer[ 1024 ];     // Single line buffer
00079     string                                  StartState;         // Found start state
00080     SStatesListProxy< string >              StatesProxy;        // List of states
00081     SStateMachineProxy< string, string >    MachineProxy;       // Machine proxy
00082 
00083     vector< string >                        Transitions;        // List of transitions
00084         // Three grammars for each type of input file lines
00085     SStartStateGrammar                      StartStateGrammar( StartState );
00086     SStatesGrammar                          StatesGrammar( StatesProxy );
00087     SEventsGrammar                          EventsGrammar( Transitions );
00088         // Line parsing result object
00089     parse_info< const char * >              Info;
00090     
00091 
00092     try
00093     {
00094             // Cycle around all lines in he input file
00095             // Note: the algorithm is not the optimal on purpose. Just to make it
00096             //       easier to read
00097         while ( Description.getline( Buffer, sizeof( Buffer ) ) )
00098         {
00099             string      SingleLine( Buffer );
00100             
00101             trim( SingleLine );
00102                 // Empty or remark lines must be skipped
00103             if ( SingleLine.empty() || SingleLine[ 0 ] == '#' )
00104             {
00105                 continue;
00106             }
00107 
00108             if ( StartState.empty() )       // Start state has not been found yet
00109             {
00110                 Info = parse( SingleLine.c_str(), StartStateGrammar, space_p );
00111                 if ( !Info.full )
00112                 {
00113                     cout << "Error. Stopped at: '" << Info.stop << endl;
00114                     break;
00115                 }
00116                 continue;
00117             }    
00118 
00119             if ( StatesProxy.GetStates().empty() )  // States list has not been found yet
00120             {
00121                 Info = parse( SingleLine.c_str(), StatesGrammar, space_p );
00122                 if ( !Info.full )
00123                 {
00124                     cout << "Error. Stopped at: '" << Info.stop << endl;
00125                     break;
00126                 }
00127                 MachineProxy << StatesProxy;
00128                 continue;
00129             }
00130         
00131                 // There should be transitions further
00132             Transitions.clear();
00133             Info = parse( SingleLine.c_str(), EventsGrammar, space_p );
00134             if ( !Info.full )
00135             {
00136                 cout << "Error. Stopped at: '" << Info.stop << endl;
00137                 break;
00138             }
00139 
00140             vector< string >::const_iterator        Current( Transitions.begin() );
00141             STransitionsProxy< string, string >     TransitionsProxy( *Current );
00142         
00143             for ( ++Current; Current != Transitions.end(); ++Current )
00144             {
00145                 if ( *Current == "NONE" )
00146                 {
00147                     TransitionsProxy << NONE;
00148                     continue;
00149                 }
00150                 if ( *Current == "EXCEPTION" )
00151                 {
00152                     TransitionsProxy << EXCEPTION;
00153                     continue;
00154                 }
00155                 TransitionsProxy << *Current;
00156             }
00157             MachineProxy << TransitionsProxy;
00158 
00159         }
00160         Description.close();
00161     }
00162     catch ( exception &  Exception )
00163     {
00164         cout << Exception.what() << endl;
00165         return 3;
00166     }
00167     catch ( ... )
00168     {
00169         cout << "Unknown exception." << endl;
00170         return 3;
00171     }
00172 
00173 
00174     
00175         // Construct the machine using the collected information
00176     SStateMachine< string, string >     TheMachine( StartState, MachineProxy );
00177     
00178     cout << "State machine start state: '" << TheMachine << "'" << endl;
00179     for ( ; ; )
00180     {
00181         string      Event;      
00182         do
00183         {
00184             cout << "Enter event name (Ctrl-C to exit): ";
00185             cin >> Event;
00186         }
00187         while ( !IsCinGood() );
00188         trim( Event );
00189         
00190         try
00191         {
00192             TheMachine << Event;        // Process the event
00193         }
00194         catch ( exception &  Exception )
00195         {
00196             cout << Exception.what() << endl;
00197         }
00198         cout << "Current state machine state: '" << TheMachine << "'" << endl;
00199     }
00200 
00201     return 0;
00202 }
00203 

Generated on Mon Aug 22 04:58:11 2005 for Example of an FSM which reads description from a file by  doxygen 1.4.4