/*
  Copyright Dave Bone 1998 - 2014
  All Rights Reserved. 
  No part of this document may be reproduced without written consent from the author.
	
FILE:		o2_err_hdlr.lex
Date:	  	8 Jul 2003
Purpose:	grammar to process errors from yacco2
Conduit:	none
Change:		11 Mar 2004 - replace tab with space so that
                          displaced error lines up properly
*/
/@
@i "/usr/local/yacco2/copyright.w"
@** |o2_err_hdlr| grammar.\fbreak
Grammar that processes for printing posted errors from yacco2.
@/
fsm	
(fsm-id "o2_err_hdlr.lex",fsm-filename o2_err_hdlr,fsm-namespace NS_o2_err_hdlr
,fsm-class Co2_err_hdlr
,fsm-version "1.0",fsm-date "8 Jul 2003",fsm-debug "false"
,fsm-comments "Logic sequencer: Print out errors from \\O2.")
@"/usr/local/yacco2/compiler/grammars/yacco2_T_includes.T"
rules{
Ro2_err_hdlr (){
  -> Rerrors eog
  -> eog
}

Rerrors (){
  -> Rerror
  -> Rerrors Rerror
}

Rerror	(
lhs{
  user-declaration
  void error_where(CAbs_lr1_sym* E_sym){
    std::string& ext_fle = yacco2::FILE_TBL__[E_sym->tok_co_ords__.external_file_id__];
    std::string line_of_data;
    std::ifstream ifile;
    ifile.open(ext_fle.c_str());
    if(ifile.good()){
        yacco2::UINT lno(1);yacco2::UINT dlno(E_sym->tok_co_ords__.line_no__);
        for(;lno<=dlno;++lno){
          getline(ifile,line_of_data);
          if(lno == dlno) break;
          line_of_data.clear();
        }      
    }      

    std::string space(" ");
    std::string::size_type f = line_of_data.find_first_of('\t');
    for(;f != std::string::npos;){
     line_of_data.replace(f,1,space);
     f = line_of_data.find_first_of('\t');
    }
    
    yacco2::lrclog << "Error in file#: " << E_sym->tok_co_ords__.external_file_id__
		<< " \"" << ext_fle.c_str() << "\"" << std::endl;
	yacco2::lrclog << line_of_data.c_str() << std::endl;
    std::cout << "Error in file#: " << E_sym->tok_co_ords__.external_file_id__
		<< " \"" << ext_fle.c_str() << "\"" << std::endl;
	std::cout << line_of_data.c_str() << std::endl;
	for(int pos = 1;pos < E_sym->tok_co_ords__.pos_in_line__;++pos){
	 yacco2::lrclog << ' ';
	 std::cout << ' ';
	}
	yacco2::lrclog << '^' << std::endl;
	yacco2::lrclog << "\tfpos: " << E_sym->tok_co_ords__.rc_pos__
		<< " line#: " << E_sym->tok_co_ords__.line_no__
		<< " cpos: " << E_sym->tok_co_ords__.pos_in_line__
		<< std::endl;
	std::cout << '^' << std::endl;
	std::cout << "\tfpos: " << E_sym->tok_co_ords__.rc_pos__
		<< " line#: " << E_sym->tok_co_ords__.line_no__
		<< " cpos: " << E_sym->tok_co_ords__.pos_in_line__
		<< std::endl;
		if(E_sym->tok_co_ords__.who_file__ != 0){
			yacco2::lrclog << "\twho thru it: " << E_sym->tok_co_ords__.who_file__
				<< " line#: " << E_sym->tok_co_ords__.who_line_no__
				<< std::endl;
			std::cout << "\twho thru it: " << E_sym->tok_co_ords__.who_file__
				<< " line#: " << E_sym->tok_co_ords__.who_line_no__
				<< std::endl;
		}
    ifile.close();
  };
  ***
}
){
  -> "nested files exceeded" {
  op
    error_where(sf->p1__);
    yacco2::lrclog << "\t" << sf->p1__->id__
    << " nested number: " << sf->p1__->nested_cnt() << std::endl;
    std::cout << "\t" << sf->p1__->id__
    << " nested number exceeded: " << sf->p1__->nested_cnt() << std::endl;
  ***
  }  
  -> "no end-of-code" {
  op
    error_where(sf->p1__);
    yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
    std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }  
  -> "no filename" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }      
  -> "bad filename" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__
   << " filename: \"" << sf->p1__->file_name()->c_str()
   << "\" does not exist" << std::endl;
   std::cout << "\t" << sf->p1__->id__
   << " filename: \"" << sf->p1__->file_name()->c_str()
   << "\" does not exist" << std::endl;
  ***
  }     
  -> "bad cmd-opt" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }       
  -> "bad int-no" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }       
  -> "bad int-no range" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }  
  -> "no int present" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }   
  -> "bad eos" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }           
  -> "bad esc" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }           
  -> "comment-overrun" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__<< std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }  
  -> "bad char" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }  	
  -> "bad univ-seq" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }
  -> "file-inclusion" "bad filename" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__;
   yacco2::lrclog << " " << sf->p2__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__;
   std::cout << " " << sf->p2__->id__ << std::endl;
  ***
  }
  -> "file-inclusion" "bad esc" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__;
   yacco2::lrclog << " " << sf->p2__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__;
   std::cout << " " << sf->p2__->id__ << std::endl;
  ***
  }
  -> "file-inclusion" "bad eos" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__;
   yacco2::lrclog << " " << sf->p2__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__;
   std::cout << " " << sf->p2__->id__ << std::endl;
  ***
  }
  -> "file-inclusion" "no filename" {
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__;
   yacco2::lrclog << " " << sf->p2__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__;
   std::cout << " " << sf->p2__->id__ << std::endl;
  ***
  }
  -> |+| {// catch balance of errors
  op
   error_where(sf->p1__);
   yacco2::lrclog << "\t" << sf->p1__->id__ << std::endl;
   std::cout << "\t" << sf->p1__->id__ << std::endl;
  ***
  }
}  
}// end of rules