/*
  Copyright Dave Bone 1998 - 2014 
  All Rights Reserved. 
  No part of this document may be reproduced without written consent from the author.
	
FILE:       o2_lcl_opts.lex
Dates:      7 Apr. 2003
*/
/@
@i "/usr/local/yacco2/copyright.w"
@** \O2's frontend command line parser.
The argv[] data passed by "int main(int argc, char* argv[])" is 
mapped into raw char tokens and placed into a container 
for lexical assessment.\fbreak
Command Format:\fbreak
file name followed by (options)* \fbreak
\fbreak
Note:\fbreak
File name can be quoted or unquoted. Safest is quoted "...".
Just watch out for unquoted: a space(s) must separate a filename from 
an option's phrase. Eg. ws.lex-g thinks the -g is part of the file name.
It should be: ws.lex\]-g. Note the space between the extension ".lex" 
and the "-g" option which separates these two phrases.\fbreak 
\fbreak          
Comments can be sprinkled throughout the command line. This was
 added to document the test driver's regressive test files. There
 is no difference in input coming from the program's command line environment
 or a test harnass's data file. The extensions: comments, and separate
 lines of command data would normally be absent when
  coming from the program's command
  line environment.\fbreak 
\INDENT{.25in}{Command Line Paramenters:}
\INDENT{.5in}{-p --- generate pdf / ps documents}
\INDENT{.5in}{-err --- generate error symbols}
\INDENT{.5in}{-t --- generate terminal symbols}
\INDENT{.5in}{all others are relics of the past --- so out damn spot}
\fbreak
Errors:\break
``comment-overrun'', ``bad-eos'', ``bad-esc'', ``bad-cmd-opt''
@/
fsm	
(fsm-id "o2_lcl_opts.lex",fsm-filename o2_lcl_opts,fsm-namespace NS_o2_lcl_opts
,fsm-class  Co2_lcl_opts {
  user-declaration
  public:
  yacco2::CHAR err_sw_;yacco2::CHAR t_sw_;
  yacco2::CHAR prt_sw_;
  std::string file_to_compile_;
  yacco2::UINT parm_cnt_;
  ***
  constructor
    err_sw_ = 'n';t_sw_ = 'n';
    prt_sw_ = 'n';
    parm_cnt_ = 1;
***
  user-prefix-declaration
#include "o2_lcl_opt.h"
#include "ws.h"
#include "eol.h"
#include "c_comments.h"
#include "xc_str.h"
#include "unq_str.h"
  ***  
  op
    parser__->set_use_all_shift_on();
  ***
}
,fsm-version "1.0",fsm-date "21 Nov. 2002",fsm-debug "false"
,fsm-comments "\\O2's command line options dispatcher.")
@"/usr/local/yacco2/compiler/grammars/yacco2_T_includes.T"

rules{
Ryacco2_options  (
lhs{
  op
    TOKEN_GAGGLE* err_queue = (TOKEN_GAGGLE*)rule_info__.parser__->error_queue();
    if(err_queue ->empty()) return;
  ***
}
){
  -> Rws_k Rparms_epi Rws_k Rfile Rws_k Reog 
}

Reog  (){	
  -> eog
  -> 
  /@
Bad data or missing option indicator: ``-'' so report it.  
  @/
|?| 
  {
    op
      rule_info__.parser__->set_use_all_shift_off();
      CAbs_lr1_sym* sym = new Err_bad_cmd_lne_opt;
      sym->set_rc(*sf->p1__,__FILE__,__LINE__);
      ADD_TOKEN_TO_ERROR_QUEUE(*sym);
      rule_info__.parser__->set_stop_parse(true);
    ***
  }
} 
 
Rws_k  (){	
  -> 
  -> Rws_k_s 
}

Rws_k_s  (){	
  -> Rws
  -> Rws_k_s Rws
}

Rws  (){	
  -> ||| "ws" NS_ws::TH_ws 
  -> ||| "comment" NS_c_comments::TH_c_comments {
    op
      sf->p2__->set_auto_delete(true);
    ***
    }
  -> ||| "eol" NS_eol::TH_eol {
    op
      sf->p2__->set_auto_delete(true);
    ***
    }
  -> ||| |?| NULL {
    op
      rule_info__.parser__->set_use_all_shift_off();
      ADD_TOKEN_TO_ERROR_QUEUE(*sf->p2__);
      rule_info__.parser__->set_stop_parse(true);
    ***
    }
}

Rfile  (
lhs{
  user-declaration
    public:
      void edit_file(CAbs_lr1_sym* Sym);
  ***
  user-implementation
      void Rfile::edit_file(CAbs_lr1_sym* Sym){
        Co2_lcl_opts* fsm = (Co2_lcl_opts*)rule_info__.parser__->fsm_tbl__;      
        using namespace NS_yacco2_err_symbols;
        using namespace NS_yacco2_k_symbols;
        std::ifstream ifile;
        ifile.open(fsm->file_to_compile_.c_str());
	    if (ifile.good()){
	      ifile.close(); 
	      return;
	    }
        CAbs_lr1_sym* sym = new Err_bad_filename(fsm->file_to_compile_);
        sym->set_rc(*Sym,__FILE__,__LINE__);
        rule_info__.parser__->add_token_to_error_queue(*sym);
        rule_info__.parser__->set_stop_parse(true);
      }
  ***
}
){	
  -> ||| "unquoted-string" NS_unq_str::TH_unq_str { 
    op
      T_unquoted_string* uqstr = sf->p2__;
      Co2_lcl_opts* fsm = (Co2_lcl_opts*)rule_info__.parser__->fsm_tbl__;      
      fsm->file_to_compile_ += uqstr->unquoted_string()->c_str();
      ++fsm->parm_cnt_;
      edit_file(uqstr);
      sf->p2__->set_auto_delete(true);
    ***
    }
  -> ||| |?| NULL {  
    op
      rule_info__.parser__->set_use_all_shift_off();
      ADD_TOKEN_TO_ERROR_QUEUE(*sf->p2__);
      rule_info__.parser__->set_stop_parse(true);
    ***
    }
  -> |?| { // no file given
    op
      rule_info__.parser__->set_use_all_shift_off();
      CAbs_lr1_sym* sym = new Err_no_filename();
        sym->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
        ADD_TOKEN_TO_ERROR_QUEUE(*sym);
        rule_info__.parser__->set_stop_parse(true);
    ***
    }
  -> ||| "xc-str" NS_xc_str::TH_xc_str { 
    op
      T_xc_str* xcstr = sf->p2__;
      Co2_lcl_opts* fsm = (Co2_lcl_opts*)rule_info__.parser__->fsm_tbl__;      
      fsm->file_to_compile_ += xcstr->c_string()->c_str();
      ++fsm->parm_cnt_;
      edit_file(xcstr);
    ***
    }
}

Rparms_epi  (){
  -> 
  -> Rparms 
}

Rparms  (){
  -> Rspec_parm Rws_k  
  -> Rparms Rspec_parm Rws_k  
}

Rspec_parm  (){	
  -> ||| "option-t" NS_o2_lcl_opt::TH_o2_lcl_opt {  
    op
      Co2_lcl_opts* fsm = (Co2_lcl_opts*)rule_info__.parser__->fsm_tbl__;      
      ++fsm->parm_cnt_;
      fsm->t_sw_ = 'y';
      sf->p2__->set_auto_delete(true);
    ***
    }
  -> ||| "option-err" NULL {  
    op
      Co2_lcl_opts* fsm = (Co2_lcl_opts*)rule_info__.parser__->fsm_tbl__;      
      ++fsm->parm_cnt_;
      fsm->err_sw_ = 'y';
      sf->p2__->set_auto_delete(true);
    ***
    }
  -> ||| "option-p" NULL {  
    op
      Co2_lcl_opts* fsm = (Co2_lcl_opts*)rule_info__.parser__->fsm_tbl__;      
      ++fsm->parm_cnt_;
      fsm->prt_sw_ = 'y';
      sf->p2__->set_auto_delete(true);
    ***
    }
  -> ||| |?| NULL {  
  /@
A false option so report it.  
  @/
    op
      rule_info__.parser__->set_use_all_shift_off();
      ADD_TOKEN_TO_ERROR_QUEUE(*sf->p2__);
      rule_info__.parser__->set_stop_parse(true);
    ***
    }
}
}// end of rules
