/* File: epsilon_rules.cpp Date and Time: Fri Jan 30 18:55:10 2015 */ #include "epsilon_rules.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_epsilon_rules;// grammar's ns // first set terminals fsm_rules_reuse_table_type::fsm_rules_reuse_table_type(){ no_rules_entries_ = 7; 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(); per_rule_s_table_[6] = new Per_rule_s_reuse_table(); } Cepsilon_rules:: Cepsilon_rules() :yacco2::CAbs_fsm ("epsilon_rules.lex" ,"1.0" ,"26 sept. 2005" ,false ,"Determine whether rules are epsilon, derive T, or are pathological." ,"Fri Jan 30 18:55:10 2015 " ,S1_Cepsilon_rules){ } Cepsilon_rules::~Cepsilon_rules(){ for(int x = 0;x < 7;++x){ ///delete fsm_rules_reuse_table.per_rule_s_table_[x]; } } bool Cepsilon_rules::failed(){ return false; } void Cepsilon_rules::op(){ rule_def_ = 0; subrule_def_ = 0; elem_t_ = 0; ip_can_ = (tok_can< AST* >*)parser__->token_supplier__; } int Cepsilon_rules::rhs_to_rules_mapping_[10] = { -1 ,0 // subrule 1 for rule 1 ,1 // subrule 2 for rule 2 ,1 // subrule 3 for rule 2 ,2 // subrule 4 for rule 3 ,3 // subrule 5 for rule 4 ,4 // subrule 6 for rule 5 ,4 // subrule 7 for rule 5 ,5 // subrule 8 for rule 6 ,6 // subrule 9 for rule 7 }; AST* Cepsilon_rules::advance_element(AST* Elemt){ AST* nxt_t = AST::brother(*Elemt);// next element for(;;){// bypass thread expression: go to jail ... eosubrule using namespace NS_yacco2_T_enum; CAbs_lr1_sym* sym = AST::content(*nxt_t); switch(sym->enumerated_id__){ case T_Enum::T_T_identifier_: break; case T_Enum::T_T_2colon_: break; case T_Enum::T_T_NULL_: break; case T_Enum::T_T_cweb_marker_: break; case T_Enum::T_T_cweb_comment_: break; default: return nxt_t; } nxt_t = AST::brother(*nxt_t);// skip thread expr: next element } } void Cepsilon_rules::deal_with_derives_list(){ // force cweave to using namespace NS_yacco2_T_enum; bool has_list_chged(false); std::list::iterator i; Read_list:; i = derives_list_.begin(); if(i == derives_list_.end()) return; for(;i != derives_list_.end();){ // force cweave elem_list_type& el = *i; CAbs_lr1_sym* rteos = AST::content(*el.elem_t_);// force cweave switch(rteos->enumerated_id__){// force cweave case T_Enum::T_refered_rule_:{ refered_rule* rr = (refered_rule*)rteos; rule_in_stbl* rstbl = rr->Rule_in_stbl(); using namespace yacco2_stbl; T_sym_tbl_report_card report_card; get_sym_entry_by_sub(report_card,rstbl->stbl_idx()); if(report_card.status_ == T_sym_tbl_report_card::failure){ report_card.err_entry_->set_rc(*rr,__FILE__,__LINE__); parser__->add_token_to_error_queue(*report_card.err_entry_); return;// caused by problem with sym. tbl } if(report_card.tbl_entry_->defined_ == false){ CAbs_lr1_sym* sym = new Err_used_rule_but_undefined; sym->set_rc(*rr,__FILE__,__LINE__); parser__->add_token_to_error_queue(*sym); // keep pouring them into the error queue has_list_chged = true;// go to next element el.elem_t_ = advance_element(el.elem_t_); ++i;// next sr in derive list break; } rule_def* r = rr->Rule_in_stbl()->r_def(); if(r->epsilon() == YES){ has_list_chged = true; el.elem_t_ = advance_element(el.elem_t_); ++i;// next sr in derive list if(el.gen_epsilon_ != EPSILON_NO){ el.gen_epsilon_ = EPSILON_MAYBE; } break; } if(r->derive_t() == YES){ has_list_chged = true; el.elem_t_ = advance_element(el.elem_t_); el.gen_epsilon_ = EPSILON_NO; ++i;// next sr in derive list break; } ++i;// indeterminate spot: next pass might free it up so next sr break; } case T_Enum::T_T_eosubrule_:{ if(el.gen_epsilon_!= EPSILON_NO){ el.rule_->epsilon(YES); el.subrule_->epsilon(YES); }else{ el.subrule_->epsilon(NO); el.rule_->derive_t(YES); } has_list_chged = true; i = derives_list_.erase(i);// finished with sr break; } case T_Enum::T_T_null_call_thread_eosubrule_:{ el.gen_epsilon_ = EPSILON_NO; el.subrule_->epsilon(NO); el.rule_->derive_t(YES); has_list_chged = true; i = derives_list_.erase(i);// finished with sr break; } case T_Enum::T_T_called_thread_eosubrule_:{ el.gen_epsilon_ = EPSILON_NO; el.subrule_->epsilon(NO); el.rule_->derive_t(YES); has_list_chged = true; i = derives_list_.erase(i);// finished with sr break; } case T_Enum::T_refered_T_:{ el.gen_epsilon_ = EPSILON_NO; el.subrule_->epsilon(NO); has_list_chged = true; el.elem_t_ = advance_element(el.elem_t_); ++i;// next sr in derive list refered_T* rt = (refered_T*)rteos; break; } default:{ // lr k el.gen_epsilon_ = EPSILON_NO; el.subrule_->epsilon(NO); has_list_chged = true; el.elem_t_ = advance_element(el.elem_t_); ++i;// next sr in derive list break; } } } if(derives_list_.empty() == true) return;// kosher grammar if(has_list_chged == true){// still o/s but going forward has_list_chged = false; goto Read_list; } } void Cepsilon_rules::deal_with_undecided_derives_list(){ // chk if undefined rules were found: yes out damn spot if(parser__->error_queue()->empty() != true) return; // errors: pathological grammar std::list::iterator i = derives_list_.begin(); if(i == derives_list_.end()) return; for(;i != derives_list_.end();++i){ elem_list_type& el = *i; CAbs_lr1_sym* elem = AST::content(*el.elem_t_); CAbs_lr1_sym* sym = new ERR_sick_grammar; sym->set_rc(*elem,__FILE__,__LINE__); parser__->add_token_to_error_queue(*sym); } } Repsilon_rules::Repsilon_rules(yacco2::Parser* P) :CAbs_lr1_sym ("Repsilon_rules",0,Cepsilon_rules::R_Repsilon_rules_,P,false,false){ } void Repsilon_rules::sr1(){ Cepsilon_rules* fsm = (Cepsilon_rules*)rule_info__.parser__->fsm_tbl__; fsm->deal_with_derives_list(); if(fsm->derives_list_.empty() != true){ fsm->deal_with_undecided_derives_list(); } } Rrules::Rrules(yacco2::Parser* P) :CAbs_lr1_sym ("Rrules",0,Cepsilon_rules::R_Rrules_,P,false,false){ } Rrule::Rrule(yacco2::Parser* P) :CAbs_lr1_sym ("Rrule",0,Cepsilon_rules::R_Rrule_,P,false,false){ } Rrule_def::Rrule_def(yacco2::Parser* P) :CAbs_lr1_sym ("Rrule_def",0,Cepsilon_rules::R_Rrule_def_,P,false,false){ } void Rrule_def::sr1(){ struct SF{ rule_def* 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); Cepsilon_rules* fsm = (Cepsilon_rules*)rule_info__.parser__->fsm_tbl__; fsm->rule_def_ = sf->p1__; } Rsubrules::Rsubrules(yacco2::Parser* P) :CAbs_lr1_sym ("Rsubrules",0,Cepsilon_rules::R_Rsubrules_,P,false,false){ } Rsubrule::Rsubrule(yacco2::Parser* P) :CAbs_lr1_sym ("Rsubrule",0,Cepsilon_rules::R_Rsubrule_,P,false,false){ } Rsubrule_def::Rsubrule_def(yacco2::Parser* P) :CAbs_lr1_sym ("Rsubrule_def",0,Cepsilon_rules::R_Rsubrule_def_,P,false,false){ } void Rsubrule_def::sr1(){ struct SF{ T_subrule_def* 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); Cepsilon_rules* fsm = (Cepsilon_rules*)rule_info__.parser__->fsm_tbl__; fsm->subrule_def_ = sf->p1__; AST* sr_t = fsm->subrule_def_->subrule_s_tree(); AST* et = AST::get_spec_child(*sr_t,1); fsm->derives_list_.push_back (elem_list_type(fsm->rule_def_,fsm->subrule_def_,et)); }