// file: $isip/class/pr/LanguageModelBNF/LanguageModelBNF.h
//

// make sure definitions are only made once
//
#ifndef ISIP_LANGUAGE_MODEL_BNF
#define ISIP_LANGUAGE_MODEL_BNF

#ifndef ISIP_LANGUAGE_MODEL_BASE
#include <LanguageModelBase.h>
#endif

#ifndef ISIP_LANGUAGE_MODEL_UNDEFINED
#include <LanguageModelUndefined.h>
#endif

// LanguageModelBase: defines the minimal interface contract for all
// language model classes
//
class LanguageModelBNF : public LanguageModelBase {

  //---------------------------------------------------------------------------
  //
  // public constants
  //
  //---------------------------------------------------------------------------
public:

  // define the class name
  //
  static const String CLASS_NAME;

  //--------------------------------------------------------------
  //
  // other important constants
  //
  //--------------------------------------------------------------
    
  //----------------------------------------
  //
  // i/o related constants
  //
  //----------------------------------------  

  static const String DEF_PARAM;
  static const String PARAM_BNF;
  static const long DEF_TAG;
  static const long MERGE_TYPE_LEN;
  
  //----------------------------------------
  //
  // default values and arguments
  //
  //----------------------------------------

  //----------------------------------------
  //
  // error codes
  //
  //----------------------------------------  

  static const long ERR = 100102;
  
  //---------------------------------------------------------------------------
  //
  // protected data
  //
  //---------------------------------------------------------------------------
protected:

  // debug level
  //
  // inherited from LanguageModelBase

  // memory manager
  //
  static MemoryManager mgr_d;

  // rule model
  //
  RuleModel rm_d;

  //---------------------------------------------------------------------------
  //
  // required public methods
  //
  //---------------------------------------------------------------------------
public:

    
  // method: name
  //
  static const String& name() {
    return CLASS_NAME;
  } 
  
  // method: diagnose
  //
  static boolean diagnose(Integral::DEBUG level);
  
  // method: debug
  //
  boolean debug(const unichar* msg) const;
  
  // constructor
  //
  LanguageModelBNF ();
  
  // method: read
  //
  boolean read(Sof& sof, long tag = LanguageModelBNF::DEF_TAG,
	       const String& cname = CLASS_NAME);
  
  // method: readData
  //
  boolean readData(Sof& sof, const String& pname = DEF_PARAM,
		   long size = SofParser::FULL_OBJECT, boolean param = true,
		   boolean nested = false);
  
  // method: write
  //
  boolean write(Sof& sof, long tag, const String& cname = CLASS_NAME) const;
  
  // method: writeData
  //
  boolean writeData(Sof& sof, const String& pname = DEF_PARAM) const;
  
  // method: sofSize
  //
  long sofSize() const {
    return rm_d.sofSize();
  }
  
  // method: assign
  //
  boolean assign(const LanguageModelBNF& lmbnf); 
  
  // method: operator=
  //
  boolean operator=(const LanguageModelBNF& lmbnf);
  
  // method: eq
  //
  boolean eq(const LanguageModelBNF& lmbnf) const;
  
  // method: operator==
  //
  boolean operator==(const LanguageModelBNF& lmbnf) const;
  
  // method: clear
  //
  boolean clear(Integral::CMODE ctype = Integral::RELEASE);
  
  //---------------------------------------------------------------------------
  //
  // class-specific public methods required by interface contract
  // defined in LanguageModelBase.h
  //
  //---------------------------------------------------------------------------

  // method: assign
  //
  boolean assign(const LanguageModelBase& arg);
  
  // method: eq
  //
  boolean eq(const LanguageModelBase& arg) const;  
  
  // method: className
  //
  const String& className() const {
    return CLASS_NAME;
  }

  // method: getRuleModel
  //
  RuleModel getRuleModel() {
    return rm_d;
  }

  // method: setRuleModel
  //
  boolean setRuleModel(const RuleModel& rm) {
    return rm_d.assign(rm);
  }

  //--------------------------------------------------------
  //
  // other methods
  //
  //--------------------------------------------------------  

  // method: minimizeGraph
  //
  boolean minimizeGraph();

  //---------------------------------------------------------------------------
  //
  // private methods
  //
  //---------------------------------------------------------------------------
private:  
  
  // method: mergeRules
  //
  boolean mergeRules(ProductionRuleSet& rules, long index1, long index2);

  // method: isValidBNF
  //
  boolean isValidBNF(ProductionRule rule);

  // method: isMergeType
  //
  boolean isMergeType(ProductionRule rule);

  // method: detectFalseLoop
  //
  boolean detectFalseLoop(String non_terminal1, String non_terminal2,
			  ProductionRuleSet rules);

  // method: getRules
  //
  ProductionRuleSet getMergeTypeRules(String non_terminal,
				      ProductionRuleSet rules);
  
  // method: findTerminals
  //
  Vector<SearchSymbol> findTerminals(ProductionRuleSet rules_a,
				     String rule_name_a);
  
};

// end of include file
// 
#endif
