/*
 File: la_expr.cpp
 Date and Time: Fri Jan 30 18:55:13 2015 
*/
#include "la_expr.h"
using namespace NS_yacco2_T_enum;// enumerate
using namespace NS_yacco2_err_symbols;// error symbols
using namespace NS_yacco2_k_symbols;// lrk 
using namespace NS_yacco2_terminals;// terminals
using namespace NS_yacco2_characters;// rc 
using namespace yacco2;// yacco2 library
using namespace NS_la_expr;// grammar's ns
// first set terminals
fsm_rules_reuse_table_type::fsm_rules_reuse_table_type(){
 no_rules_entries_ = 6;
 per_rule_s_table_[0] =  new Per_rule_s_reuse_table();
 per_rule_s_table_[1] =  new Per_rule_s_reuse_table();
 per_rule_s_table_[2] =  new Per_rule_s_reuse_table();
 per_rule_s_table_[3] =  new Per_rule_s_reuse_table();
 per_rule_s_table_[4] =  new Per_rule_s_reuse_table();
 per_rule_s_table_[5] =  new Per_rule_s_reuse_table();
}
  Cla_expr::
  Cla_expr()
    :yacco2::CAbs_fsm
      ("la_expr.lex"
      ,"1.0"
      ,"24 mar 2004"
      ,false
      ,"Parse the lookahead expression after chaffe removed."
      ,"Fri Jan 30 18:55:13 2015 "
      ,S1_Cla_expr){
    
    ddd_idx_ = 0;
    ddd_[ddd_idx_] = 0;
    gps_for_error_reporting_ = 0;
 
  }
 
Cla_expr::~Cla_expr(){

  for(int x = 0;x < 6;++x){
   ///delete fsm_rules_reuse_table.per_rule_s_table_[x];
  }
} 

  bool Cla_expr::failed(){
      return false;
  }
  void Cla_expr::op(){
    ddd_idx_ = 0;
    ddd_[ddd_idx_] = 0;
    gps_for_error_reporting_ = 0;
  
}
int Cla_expr::rhs_to_rules_mapping_[12] = {
 -1
 ,0 // subrule 1 for rule 1
 ,1 // subrule 2 for rule 2
 ,1 // subrule 3 for rule 2
 ,1 // subrule 4 for rule 2
 ,1 // subrule 5 for rule 2
 ,2 // subrule 6 for rule 3
 ,3 // subrule 7 for rule 4
 ,3 // subrule 8 for rule 4
 ,3 // subrule 9 for rule 4
 ,4 // subrule 10 for rule 5
 ,5 // subrule 11 for rule 6
}; 

    void Cla_expr::copy_str_into_buffer(std::string* Str){   
      const char* y = Str->c_str(); 
      int x(0);
      for(;y[x]!=0;++x,++ddd_idx_)ddd_[ddd_idx_] = y[x];
      ddd_[ddd_idx_] = 0;
    }
    void Cla_expr::copy_kstr_into_buffer(const char* Str){
      const char* y = Str; 
      int x(0);
      for(;y[x]!=0;++x,++ddd_idx_)ddd_[ddd_idx_] = y[x];
      ddd_[ddd_idx_] = 0;
    }
    void Cla_expr::unionize_sets(T_IN_STBL_SET_type* Add_to_set
          ,T_IN_STBL_SET_type* A_set,T_IN_STBL_SET_type* B_set){
		if(A_set->find(STBL_T_ITEMS[LR1_Eolr]) !=A_set->end()){
			Add_to_set->insert(A_set->begin(),A_set->end());
			return;		
		}    
		if(B_set->find(STBL_T_ITEMS[LR1_Eolr]) !=B_set->end()){
			Add_to_set->insert(B_set->begin(),B_set->end());
			return;		
		}
		Add_to_set->insert(A_set->begin(),A_set->end());
		Add_to_set->insert(B_set->begin(),B_set->end());
    }
    void Cla_expr::explode_eolr(T_IN_STBL_SET_type* A_set){
      A_set->clear();
      T_enum_phrase* e_p =  O2_T_ENUM_PHASE;
      A_set->insert(STBL_T_ITEMS[LR1_Eog]);// eog

      int tt = e_p->total_enumerate();
      for(int x=8;x<tt;++x){// balance of meta Ts bypassed. Start from RC
        A_set->insert(STBL_T_ITEMS[x]);
      }
    }
    void Cla_expr::set_differences(T_IN_STBL_SET_type* Add_to_set
                ,T_IN_STBL_SET_type* A_set
		,T_IN_STBL_SET_type* B_set){
		if(A_set->find(STBL_T_ITEMS[LR1_Eolr]) !=A_set->end()){
			explode_eolr(A_set);
		}    
		if(B_set->find(STBL_T_ITEMS[LR1_Eolr]) !=B_set->end()){
			explode_eolr(B_set);
		}
		if(A_set->empty() == true){
			CAbs_lr1_sym* sym = new Err_empty_set_removal_in_la_expr;
			sym->set_rc(*gps_for_error_reporting_,__FILE__,__LINE__);
			parser__->set_stop_parse(true);
			ADD_TOKEN_TO_ERROR_QUEUE_FSM(*sym);
                        parser__->set_abort_parse(true);
		}

		T_IN_STBL_SET_ITER_type Ai = A_set->begin();
		T_IN_STBL_SET_ITER_type Aie = A_set->end();
		T_IN_STBL_SET_ITER_type Bie = B_set->end();
		
		T_IN_STBL_SET_ITER_type AinBi;
		for(;Ai != Aie;++Ai){		  
		  AinBi = B_set->find(*Ai);
		  if(AinBi != Bie){
		    continue; // bypass
		  }
		  Add_to_set->insert(*Ai);
		}
    }
    void Cla_expr::add_element_to_set(T_in_stbl* Elem,T_IN_STBL_SET_type* Set_to_add_to){
      if(Set_to_add_to->find(STBL_T_ITEMS[LR1_Eolr]) != Set_to_add_to->end()) return;
      if(Elem  == STBL_T_ITEMS[LR1_Eolr]){
        Set_to_add_to->clear();
      }
      Set_to_add_to->insert(Elem);
    }
    
    void Cla_expr::add_rule_to_set
		(NS_yacco2_terminals::rule_def* Rule
		,T_IN_STBL_SET_type* Set_to_add_to
		,std::set<int>* Rules_already_processed){
		using namespace NS_yacco2_terminals;
		int r_id = Rule->enum_id();
		if(Rules_already_processed->find(r_id) !=Rules_already_processed->end()) return;
		Rules_already_processed->insert(r_id);
		AST* r_t = Rule->rule_s_tree();
		set<yacco2::INT> elem_filter;
        elem_filter.insert(NS_yacco2_T_enum::T_Enum::T_T_subrule_def_);
		tok_can_ast_functor ast_functor;
        ast_prefix_wbreadth_only pwbo(*r_t,&ast_functor,&elem_filter,true);
        tok_can<AST*> tok_can(pwbo);
        for (int xxx = 0;tok_can.operator[](xxx) != yacco2::PTR_LR1_eog__;++xxx){
          T_subrule_def* sr_def = (T_subrule_def*)tok_can.operator[](xxx);
          vector<CAbs_lr1_sym*>* elems_list = sr_def->subrule_elems();
          CAbs_lr1_sym* sym = (*elems_list)[0];
          int id = sym->enumerated_id__;
          switch(id){
            case NS_yacco2_T_enum::T_Enum::T_T_eosubrule_: break;
            case NS_yacco2_T_enum::T_Enum::T_refered_T_: {
              refered_T* rt = (refered_T*)sym;
              add_element_to_set(rt->t_in_stbl(),Set_to_add_to);
              break;
            }
            case NS_yacco2_T_enum::T_Enum::T_refered_rule_: {
              refered_rule* rt = (refered_rule*)sym;
              rule_def* r = rt->Rule_in_stbl()->r_def();
              add_rule_to_set(r,Set_to_add_to,Rules_already_processed);
              break;
            }
            default:{
            }
          }
          
        }
    }
  
Rla_expr::Rla_expr(yacco2::Parser* P)
 :CAbs_lr1_sym
  ("Rla_expr",0,Cla_expr::R_Rla_expr_,P,false,false){
}

void Rla_expr::sr1(){
  struct SF{
   Re* p1__;
   State* s1__;
   bool abort1__;
   Rule_s_reuse_entry* rule_s_reuse_entry1__;
   LR1_eog* p2__;
   State* s2__;
   bool abort2__;
   Rule_s_reuse_entry* rule_s_reuse_entry2__;
  };
  SF* sf = (SF*)rule_info__.parser__->parse_stack__.sf_by_top(2);
  
      Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
      if(sf->p1__->fset_.empty() == true){
		  CAbs_lr1_sym* sym = new Err_la_expr_calc_empty_set;
		  sym->set_rc(*fsm->gps_for_error_reporting_,__FILE__,__LINE__);
		  ADD_TOKEN_TO_ERROR_QUEUE(*sym);
		  rule_info__.parser__->set_abort_parse(true);
      }
      T_parallel_parser_phrase* la_ph = O2_PP_PHASE;
      T_parallel_la_boundary* la = la_ph->la_bndry();
      la->la_first_set(sf->p1__->fset_);
      la->cweb_la_srce_expr((const char*)&fsm->ddd_);
  
}

Re::Re(yacco2::Parser* P)
 :CAbs_lr1_sym
  ("Re",0,Cla_expr::R_Re_,P,false,false){
}

void Re::ctor(){
 
    fset_.clear();
 
}
void Re::sr1(){
  struct SF{
   Re* p1__;
   State* s1__;
   bool abort1__;
   Rule_s_reuse_entry* rule_s_reuse_entry1__;
   Rplus* p2__;
   State* s2__;
   bool abort2__;
   Rule_s_reuse_entry* rule_s_reuse_entry2__;
   Rt* p3__;
   State* s3__;
   bool abort3__;
   Rule_s_reuse_entry* rule_s_reuse_entry3__;
  };
  SF* sf = (SF*)rule_info__.parser__->parse_stack__.sf_by_top(3);
  
      Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
      fset_.clear();
      fsm->unionize_sets(&fset_,&sf->p1__->fset_,&sf->p3__->fset_);
    
}

void Re::sr2(){
  struct SF{
   Re* p1__;
   State* s1__;
   bool abort1__;
   Rule_s_reuse_entry* rule_s_reuse_entry1__;
   Rminus* p2__;
   State* s2__;
   bool abort2__;
   Rule_s_reuse_entry* rule_s_reuse_entry2__;
   Rt* p3__;
   State* s3__;
   bool abort3__;
   Rule_s_reuse_entry* rule_s_reuse_entry3__;
  };
  SF* sf = (SF*)rule_info__.parser__->parse_stack__.sf_by_top(3);
  
      Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
      fset_.clear();
      fsm->set_differences(&fset_,&sf->p1__->fset_,&sf->p3__->fset_);
    
}

void Re::sr4(){
  struct SF{
   Rt* p1__;
   State* s1__;
   bool abort1__;
   Rule_s_reuse_entry* rule_s_reuse_entry1__;
  };
  SF* sf = (SF*)rule_info__.parser__->parse_stack__.sf_by_top(1);
  
      fset_.clear();
      fset_.insert(sf->p1__->fset_.begin(),sf->p1__->fset_.end());
    
}

Rerr_bad_oper::Rerr_bad_oper(yacco2::Parser* P)
 :CAbs_lr1_sym
  ("Rerr_bad_oper",0,Cla_expr::R_Rerr_bad_oper_,P,false,false){
}

void Rerr_bad_oper::sr1(){
  struct SF{
   CAbs_lr1_sym* p1__;
   State* s1__;
   bool abort1__;
   Rule_s_reuse_entry* rule_s_reuse_entry1__;
  };
  SF* sf = (SF*)rule_info__.parser__->parse_stack__.sf_by_top(1);
  
      CAbs_lr1_sym* sym = new Err_bad_operator_in_la_expr;
      sym->set_rc(*sf->p1__,__FILE__,__LINE__);
      ADD_TOKEN_TO_ERROR_QUEUE(*sym);
      rule_info__.parser__->set_abort_parse(true);
    
}

Rt::Rt(yacco2::Parser* P)
 :CAbs_lr1_sym
  ("Rt",0,Cla_expr::R_Rt_,P,false,false){
}

void Rt::ctor(){
 
    fset_.clear();
 
}
void Rt::sr1(){
  struct SF{
   T_in_stbl* p1__;
   State* s1__;
   bool abort1__;
   Rule_s_reuse_entry* rule_s_reuse_entry1__;
  };
  SF* sf = (SF*)rule_info__.parser__->parse_stack__.sf_by_top(1);
  
   fset_.clear();
     using namespace NS_yacco2_terminals;
      Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
      T_terminal_def* dt = sf->p1__->t_def();
      fsm->copy_kstr_into_buffer(" ");
      char xlate_file[Max_cweb_item_size];
      XLATE_SYMBOLS_FOR_cweave(dt->t_name()->c_str(),xlate_file);
      fsm->copy_kstr_into_buffer(xlate_file);
      fset_.clear();
      fset_.insert(sf->p1__);
    
}

void Rt::sr2(){
  struct SF{
   rule_in_stbl* p1__;
   State* s1__;
   bool abort1__;
   Rule_s_reuse_entry* rule_s_reuse_entry1__;
  };
  SF* sf = (SF*)rule_info__.parser__->parse_stack__.sf_by_top(1);
  
    fset_.clear();
    using namespace NS_yacco2_terminals;
      Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
      rule_def* rt = sf->p1__->r_def();
      fsm->copy_kstr_into_buffer(" ");
      char xlate_file[Max_cweb_item_size];
      XLATE_SYMBOLS_FOR_cweave(rt->rule_name()->c_str(),xlate_file);
      fsm->copy_kstr_into_buffer(xlate_file);

      std::set<int> already_processed_rules;
      fsm->add_rule_to_set(rt,&fset_,&already_processed_rules);
    
}

void Rt::sr3(){
  struct SF{
   CAbs_lr1_sym* p1__;
   State* s1__;
   bool abort1__;
   Rule_s_reuse_entry* rule_s_reuse_entry1__;
  };
  SF* sf = (SF*)rule_info__.parser__->parse_stack__.sf_by_top(1);
  
  fset_.clear();
    using namespace NS_yacco2_terminals;
    int id = sf->p1__->enumerated_id__;
    switch(id){
		case T_Enum::T_LR1_all_shift_operator_:{
           Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
           fsm->copy_kstr_into_buffer(" $|+|$");
               fsm->add_element_to_set(STBL_T_ITEMS[id],&fset_);
          break; 
		}
		case T_Enum::T_LR1_invisible_shift_operator_:{
           Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
           fsm->copy_kstr_into_buffer(" $|.|$");
                fsm->add_element_to_set(STBL_T_ITEMS[id],&fset_);
          break; 
		}
		case T_Enum::T_LR1_parallel_operator_:{
           Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
           fsm->copy_kstr_into_buffer(" $|||$");
                fsm->add_element_to_set(STBL_T_ITEMS[id],&fset_);
          break; 
		}
		case T_Enum::T_LR1_fset_transience_operator_:{
           Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
           fsm->copy_kstr_into_buffer(" $|t|$");
                fsm->add_element_to_set(STBL_T_ITEMS[id],&fset_);
          break; 
		}

		case T_Enum::T_LR1_reduce_operator_:{
           Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
           fsm->copy_kstr_into_buffer(" $|r|$");
                fsm->add_element_to_set(STBL_T_ITEMS[id],&fset_);
          break; 
		}
		default:{
			CAbs_lr1_sym* sym = new Err_bad_term_in_la_expr;
			sym->set_rc(*sf->p1__,__FILE__,__LINE__);
			rule_info__.parser__->set_stop_parse(true);
			ADD_TOKEN_TO_ERROR_QUEUE(*sym);
            rule_info__.parser__->set_abort_parse(true);
		  }
    }
    
}

Rminus::Rminus(yacco2::Parser* P)
 :CAbs_lr1_sym
  ("Rminus",0,Cla_expr::R_Rminus_,P,false,false){
}

void Rminus::sr1(){
  struct SF{
   raw_minus* p1__;
   State* s1__;
   bool abort1__;
   Rule_s_reuse_entry* rule_s_reuse_entry1__;
  };
  SF* sf = (SF*)rule_info__.parser__->parse_stack__.sf_by_top(1);
  
      Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
      fsm->gps_for_error_reporting_=sf->p1__;
      fsm->copy_kstr_into_buffer(" $-$");
    
}

Rplus::Rplus(yacco2::Parser* P)
 :CAbs_lr1_sym
  ("Rplus",0,Cla_expr::R_Rplus_,P,false,false){
}

void Rplus::sr1(){
  
      Cla_expr* fsm = (Cla_expr*)rule_info__.parser__->fsm_tbl__;
      fsm->copy_kstr_into_buffer(" $+$");
    
}

