/*
  Copyright Dave Bone 1998 - 2014 
  All Rights Reserved. 
  No part of this document may be reproduced without written consent from the author.
	
FILE:       prefile_include.lex
Dates:      17 Juin 2003
Purpose:    file name recognizer for includes
Returned:   T_file_inclusion
            One of the following errors can be included within T_file_inclusion
              Lr1_err_bad_filename
              Lr1_err_bad_esc
              Lr1_err_bad_eos
              Lr1_err_no_filename
*/
/@
@i "/usr/local/yacco2/copyright.w"
@** |prefile_include| Thread.\fbreak
File name recognizer for includes.
It checks the file system to 
verify that the file exists.
Inside the returned ``file-inclusion'' terminal
is the file open findings whether the file name exists.
It is up to the caller to check this error status.
A null status means it's okay while ``bad filename''
error symbol with the extracted filename string
is used.
@/
fsm	
(fsm-id	"prefile_include.lex",fsm-filename prefile_include,fsm-namespace NS_prefile_include
,fsm-class		Cprefile_include{
  user-prefix-declaration
#include "ws.h"
#include "eol.h"
#include "c_string.h"
using namespace NS_yacco2_terminals;
  ***
  user-declaration
    public:
		T_c_string* chrs_;
		yacco2::CAbs_lr1_sym* error_raised_;
  ***
  op
    chrs_ = 0;
    error_raised_ = 0;
  ***
  constructor
    chrs_ = 0;
    error_raised_ = 0;
  ***
  }
,fsm-version	"1.0"	,fsm-date		"17 Juin 2003"
,fsm-debug		"false"	
,fsm-comments	"Preprocessor source file from the ``include file'' directive.")
parallel-parser	
(	
  parallel-thread-function
    TH_prefile_include
  ***
  parallel-la-boundary
    eolr
  ***
)
@"/usr/local/yacco2/compiler/grammars/yacco2_T_includes.T"

rules{
Rprefile_include (
lhs{
  op
    Cprefile_include* fsm = (Cprefile_include*) rule_info__.parser__->fsm_tbl__;
    T_file_inclusion* typ = new T_file_inclusion(fsm->chrs_,fsm->error_raised_);
    typ->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__);
    RSVP(typ);
	fsm->chrs_=0;
  ***
  }
){	
  -> "@" Rpossible_ws  Rfile_string Reof 
}

Reof  (){
  -> |.|	// eof,eog type error
  ->  ||| eol NS_eol::TH_eol 
}

Rpossible_ws  (){
  -> |.|    // shift out conflict
  -> ||| "ws" NS_ws::TH_ws
}

Rfile_string  (){
  -> ||| "c-string"	NS_c_string::TH_c_string{
    op
	Cprefile_include* fsm = (Cprefile_include*) rule_info__.parser__->fsm_tbl__;
      fsm->chrs_ = sf->p2__;
      string* ps_fn = fsm->chrs_->c_string();
      std::ifstream fle_chk;
      fle_chk.open(ps_fn->c_str());
      if(!fle_chk.good()){
        fsm->error_raised_ = new Err_bad_filename(*ps_fn);
        fsm->error_raised_->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__);
      }else{
        fle_chk.close();
      }
    ***			
    } 
  -> ||| "bad eos" NULL{
    op
	  Cprefile_include* fsm = (Cprefile_include*) rule_info__.parser__->fsm_tbl__;
      fsm->error_raised_ = sf->p2__;
    ***			
    } 
  -> ||| "bad esc" NULL{
    op
	  Cprefile_include* fsm = 
	(Cprefile_include*) rule_info__.parser__->fsm_tbl__;
      fsm->error_raised_ = sf->p2__;
   ***			
    } 
  -> |?| {
    op
	  Cprefile_include* fsm = (Cprefile_include*) rule_info__.parser__->fsm_tbl__;
      fsm->error_raised_ = new Err_no_filename;
      fsm->error_raised_->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
    ***			
    } 
  ->  ||| |?| NULL {
      op
        Cprefile_include* fsm = 
	(Cprefile_include*) rule_info__.parser__->fsm_tbl__;
        fsm->error_raised_ = sf->p2__;
      ***
      }
}
}// end of rules