/*
  Copyright Dave Bone 1998 - 2014 
  All Rights Reserved. 
  No part of this document may be reproduced without written consent from the author.
	
FILE:    t_alphabet.lex
dates:   10 feb. 2005	
Purpose: parse of t-alphabet language.
         put T into global T dictionary, yacco2's symbol table
         and global thread list per terminal.
*/
/@
@i "/usr/local/yacco2/copyright.w"
@** |t_alphabet| grammar.\fbreak
Parse Linker's t-alphabet language. 
It's just a list of terminal names.
\fbreak
For the Yacco2 grammars, it looks like this:\fbreak
\listing{"/usr/local/yacco2/diagrams+etc/intro2.txt"}
\fbreak
 @/
fsm	
(fsm-id "t_alphabet.lex",fsm-filename t_alphabet,fsm-namespace NS_t_alphabet
,fsm-class Ct_alphabet{
  user-prefix-declaration
	#include "yacco2_stbl.h"
    extern std::vector<NS_yacco2_terminals::table_entry*> T_DICTIONARY;
    extern std::vector< std::set<int> > T_THREAD_ID_LIST;
  ***
  user-declaration
    public:
    std::map<int,std::string> enum_T_dictionary_;
    std::map<std::string,int> T_dictionary_;
    int enum_cnt_;
  ***
  constructor
    enum_cnt_ = 0;
  ***
}
,fsm-version	"1.0",fsm-date "9 Feb. 2005",fsm-debug "false"
,fsm-comments	"Parse Linker's t-alphabet language.")
@"/usr/local/yacco2/compiler/grammars/yacco2_T_includes.T"

rules{
Rt_alphabet  (
lhs{
  op
       using namespace NS_yacco2_k_symbols;
       ADD_TOKEN_TO_PRODUCER_QUEUE(*yacco2::PTR_LR1_eog__);   
       ADD_TOKEN_TO_PRODUCER_QUEUE(*yacco2::PTR_LR1_eog__);  
  ***
  }
){
  -> RT_alphabet
		Rlist_of_Ts	
	 Rend_T_alphabet 
	 Reog
}
Reog  (){
  -> eog {
    op 
 	  Ct_alphabet* fsm = (Ct_alphabet*) rule_info__.parser__->fsm_tbl__;
      if(fsm->T_dictionary_.empty()){
        CAbs_lr1_sym* sym = new Err_no_terminals_present_in_T_alphabet;
        sym->set_rc(*sf->p1__,__FILE__,__LINE__);
        ADD_TOKEN_TO_ERROR_QUEUE(*sym);
        rule_info__.parser__->set_stop_parse(true);
      }
    ***
    }  
}

RT_alphabet  (){
  -> "T-alphabet"
  ->  |?| {
    op
      CAbs_lr1_sym* sym = new Err_T_alphabet_kw_not_present;
      sym->set_rc(*sf->p1__,__FILE__,__LINE__);
      ADD_TOKEN_TO_ERROR_QUEUE(*sym);
      rule_info__.parser__->set_stop_parse(true);
    ***
    }
}

Rlist_of_Ts  (){
  -> 	Ra_T 
  -> 	Rlist_of_Ts Ra_T  
  -> |?| { 
/@
 no terminals in list: \fbreak
 REMEMBER THERE IS NO ASSOCIATED CO-ORDINATES, USE CURRENT TOKEN.
@/
    op
          CAbs_lr1_sym* sym = new Err_no_terminals_in_T_alphabet_list;
       sym->set_rc(*sf->p1__,__FILE__,__LINE__); 
       ADD_TOKEN_TO_ERROR_QUEUE(*sym);
       rule_info__.parser__->set_stop_parse(true);
    ***			
	}
}

Ra_T  (){
  -> identifier {
    op
 	  Ct_alphabet* fsm = (Ct_alphabet*) rule_info__.parser__->fsm_tbl__;
      T_identifier* k = sf->p1__;
      // add to T dictionary
      std::map<std::string,int>::iterator i = 
	fsm->T_dictionary_.find(k->identifier()->c_str());
      if(i != fsm->T_dictionary_.end()){
        CAbs_lr1_sym* sym = new Err_dup_entry_in_sym_table;
        sym->set_rc(*sf->p1__,__FILE__,__LINE__); 
        ADD_TOKEN_TO_ERROR_QUEUE(*sym);
        rule_info__.parser__->set_stop_parse(true);
        return;
      }
      fsm->T_dictionary_[k->identifier()->c_str()]=fsm->enum_cnt_;
      string xxx(k->identifier()->c_str());
      fsm->enum_T_dictionary_[fsm->enum_cnt_] = xxx;
	  using namespace yacco2_stbl;
	  T_sym_tbl_report_card report_card;
	  T_attributes* T_att = new T_attributes(k->identifier()->c_str(),fsm->enum_cnt_);
	  tth_in_stbl* t = new tth_in_stbl(T_att,k,rule_info__.parser__);
	  add_sym_to_stbl(report_card,*k->identifier()->c_str()
		,*t,table_entry::defed,table_entry::terminal);
	  	if(report_card.status_ != T_sym_tbl_report_card::okay){
			report_card.err_entry_->set_rc(*sf->p1__,__FILE__,__LINE__);
			ADD_TOKEN_TO_ERROR_QUEUE(*report_card.err_entry_);
			rule_info__.parser__->set_stop_parse(true);
			return;
		}
	  t->stbl_idx(report_card.pos_);
      T_DICTIONARY.push_back(report_card.tbl_entry_);
      T_THREAD_ID_LIST.push_back(std::set<int>());
      ++fsm->enum_cnt_;
    ***			
    } 
}

Rend_T_alphabet  (){
  -> "end-T-alphabet"
  -> |?| { 
  /@
  Random characters or eog to err or not to ?
  @/
    op
       CAbs_lr1_sym* sym = new Err_end_T_alphabet_kw_not_present;
       sym->set_rc(*sf->p1__,__FILE__,__LINE__); 
       ADD_TOKEN_TO_ERROR_QUEUE(*sym);
       rule_info__.parser__->set_stop_parse(true);
    ***			
	}
}
}// end of rules
