Advertisement
ifknot

Finite State Machine

Nov 6th, 2011
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.74 KB | None | 0 0
  1. #ifndef FSM_H_
  2. #define FSM_H_
  3.  
  4. #include <set>
  5. #include <map>
  6. #include <vector>
  7. #include <string>
  8. #include <sstream>
  9. #include <iterator>
  10.  
  11. using namespace std;
  12.  
  13. namespace jst {
  14.  
  15.     namespace parsers {
  16.  
  17.     /**
  18.      * classic FSM tuple
  19.      * q0   start state
  20.      * Q    set of states
  21.      * F    subset of accepting states in Q
  22.      * Σ   input alphabet
  23.      * δ   state transition function
  24.      */
  25.     template<typename State, typename Input, typename Payload>
  26.     class FSM {
  27.  
  28.     public:
  29.  
  30.         struct Action {
  31.             virtual void action(FSM<State, Input, Payload>& fsm) = 0;
  32.         };
  33.  
  34.         typedef set<State> state_set;
  35.         typedef set<Input> input_set;
  36.         typedef map<string, Action*> transducer_map;
  37.  
  38.     private:
  39.  
  40.         typedef vector< vector< pair<State, Action*> > > transition_table;
  41.  
  42.     public:
  43.  
  44.         /**
  45.          * q starting state, p starting payload, Q legal states, F accepting states, Σ legal input, A transducer actions, Ad optional default action, Aa optional accepting action, Ar optional rejecting action
  46.          */
  47.         FSM(State q, Payload p, state_set& Q, state_set& F, input_set& Σ, transducer_map& A, Action* Ad = 0, Action* Aa = 0, Action* Ar = 0):
  48.             q0(q),
  49.             q(q0),
  50.             P0(p),
  51.             P(P0),
  52.             Q(Q),
  53.             F(F),
  54.             Σ(Σ),
  55.             A(A),
  56.             Ad(Ad),
  57.             Aa(Aa),
  58.             Ar(Ar),
  59.             δ(vector<vector< pair<State, Action*> > >(Q.size(), vector< pair<State, Action*> >(Σ.size(),pair<State, Action*>(q0, 0)))) {}
  60.  
  61.         /**
  62.          * specify transitions
  63.          * r1 start state, a the input, r2 target state, At optional transducer action fired on state change
  64.          */
  65.         void  add(State r1, Input a, State r2, string t) {
  66.             δ[distance(Q.begin(), Q.find(r1))][distance(Σ.begin(), Σ.find(a))] = pair<State, Action*>(r2, A[t]);
  67.         }
  68.  
  69.         Payload& payload() {
  70.             return(P);
  71.         }
  72.  
  73.         bool process(input_set& w) {
  74.             for(typename input_set::const_iterator ai = w.begin(); ai != w.end(); ++ai)
  75.                 doTransition(q,*ai);
  76.             if(F.find(q) != F.end())
  77.                 return(accepts());
  78.             else
  79.                 return(rejects());
  80.         }
  81.  
  82.         void reset() {
  83.             q =q0;
  84.             P = P0;
  85.         }
  86.  
  87.         const State state() const {
  88.             return q;
  89.         }
  90.  
  91.         string toString() const {
  92.             stringstream ss;
  93.             ss << "FSM intially " << q0 << " currently " << q << (F.find(q) != F.end() ?"(accepting)" :"(rejecting)") << " payload " << P << endl << "legal states: ";
  94.             for(typename state_set::iterator i = Q.begin(); i != Q.end(); ++i)
  95.                 ss << *i << " ";
  96.             ss << endl << "accepting states: ";
  97.             for(typename state_set::iterator i = F.begin(); i != F.end(); ++i)
  98.                 ss << *i << " ";
  99.             ss << endl << "legal inputs: ";
  100.             for(typename input_set::iterator i = Σ.begin(); i != Σ.end(); ++i)
  101.                 ss << *i << " ";
  102.             ss << endl << "transition table:" << endl;
  103.             for(int i = 0; i < Q.size(); ++i) {
  104.                 for(int j = 0; j < Σ.size(); ++j) {
  105.                     ss << δ[i][j].first << " ";
  106.                 }
  107.                 ss << endl;
  108.             }
  109.             return(ss.str());
  110.         }
  111.  
  112.         virtual ~FSM() {}
  113.  
  114. protected:
  115.  
  116.         bool accepts() {
  117.             if(Aa)
  118.                 Aa->action(*this);
  119.             return(true);
  120.         }
  121.  
  122.         bool defaults() {
  123.             if(Ad)
  124.                 Ad->action(*this);
  125.             return(false);
  126.         }
  127.  
  128.         void doTransition(State r, Input a) {
  129.             typename state_set::const_iterator ri = Q.find(r);
  130.             typename input_set::const_iterator ai = Σ.find(a);
  131.             if(ri != Q.end() && ai != Σ.end()) {
  132.                 pair<State, Action*> qA = δ[distance(Q.begin(), ri)][distance(Σ.begin(), ai)];
  133.                 q = qA.first;
  134.                 if(qA.second)
  135.                     qA.second->action(*this);
  136.             }
  137.             else
  138.                 defaults();
  139.         }
  140.  
  141.         bool rejects() {
  142.             if(Ar)
  143.                 Ar->action(*this);
  144.             return(false);
  145.         }
  146.  
  147. private:
  148.  
  149.         State q0;
  150.         State q;
  151.         Payload P0;
  152.         Payload P;
  153.  
  154.         state_set& Q;
  155.         state_set& F;
  156.         input_set& Σ;
  157.         transducer_map& A;
  158.  
  159.         Action* Ad;
  160.         Action* Aa;
  161.         Action* Ar;
  162.  
  163.         transition_table δ;// Q column Σ row table defines δ
  164.  
  165.  
  166.     };
  167.  
  168.     }
  169.  
  170. }
  171.  
  172. #endif /* FSM_H_ */
  173.  
  174.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement