#ifndef _FSM_H_INCLUDED_
#define _FSM_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// FSM.h
// -----
// Dragon final state machine interface definition
//                                                         
// Design and Implementation by Bjoern Lemke               
//                                                         
// (C)opyright 2007 by Bjoern Lemke
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// INTERFACE MODULE
//
// Class: FSM
// 
// Description: implementation of a final state machine for lexical analysis
//
//////////////////////////////////////////////////////////////////////////////

// BASE INCLUDES
#include <lfc/Chain.h>
#include <lfc/TreeT.h>
#include <lfc/SetT.h>

// DRAGON INCLUDES
#include "FSMState.h"
#include "FSMTransition.h"

class FSM {

 public:

  FSM(TreeT<FSMState>* pStateTable, TreeT<FSMTransition>* pTransitionTable);
  ~FSM();

  void epsilonFree();
  void determinate();
  void invert();

  unsigned long States();
  unsigned long Transitions();
  void printFsm();

 private:


  class PowerState;
  class PowerTransition;
  
  TreeT<FSMState> *_pStateTable;
  TreeT<FSMTransition> *_pTransitionTable;
  
  void buildEpsilonClosure(unsigned long state, SetT<unsigned long>& closureSet);

  class EpsilonClosureMap {
      
  public:

      EpsilonClosureMap();
      EpsilonClosureMap(unsigned long state);
      EpsilonClosureMap(unsigned long state, SetT<unsigned long>& closure);
      
      EpsilonClosureMap operator = (const EpsilonClosureMap& m);

      bool operator == (EpsilonClosureMap m);

      bool operator < (EpsilonClosureMap m);
      bool operator > (EpsilonClosureMap m);


      long getState();
      SetT<unsigned long>& getClosure();
      
  private:
      
      unsigned long _state;
      SetT<unsigned long> _closure;
      
  };
  
  class PowerState {

  public:
    
    PowerState();
    PowerState(const TreeT<FSMState>& stateSet);
    PowerState(const TreeT<FSMState>& stateSet, unsigned long id, StateType type);
    ~PowerState();
    
    PowerState(const PowerState& p);  
    PowerState& operator = (const PowerState& p);    
    bool operator == (PowerState p);

    bool operator < (PowerState p);
    bool operator > (PowerState p);
    

    void setType(StateType type);
    void setToken(const Chain& token);

    TreeT<FSMState>& getStateSet();
    unsigned long getId();
    StateType getType();
    const Chain& getToken();

  private:
    
    TreeT<FSMState> _stateSet; 
    unsigned long  _id;
    StateType _type;
    Chain  _token;
  };



  class PowerTransition {

  public:
    
    PowerTransition();
    PowerTransition(const TreeT<FSMState>& source, const TreeT<FSMState>& target, char sign);
    ~PowerTransition();
    
    PowerTransition(const PowerTransition& x);  
    PowerTransition& operator = (const PowerTransition& x);    
    bool operator == (PowerTransition x);
    
    bool operator > (PowerTransition x);
    bool operator < (PowerTransition x);
    
    TreeT<FSMState>& getSource();
    TreeT<FSMState>& getTarget();
    char getSign();

  private:
    
    TreeT<FSMState> _source; 
    TreeT<FSMState>  _target;
    char _sign;

  };

  

};


#endif

