/*
  Copyright Dave Bone 1998 - 2014 
  All Rights Reserved. 
  No part of this document may be reproduced without written consent from the author.
	
FILE:       c_comments.lex
Dates:      17 Juin 2003
Test file:  c_comments.dat
Purpose:    "C++" styled comments
Returned:	comment
            Err_comment_overrun
*/
/@
@i "/usr/local/yacco2/copyright.w"
@** |c_comments| Thread.\fbreak
Handles both flavours of c++ comments.\fbreak
\ptindent{1) // single line type comment}
\ptindent{2) /* ... */ type comment}
To speed things up, i'm using a finite-state approach to lower the 
pushdown deterministic rule push / pop cycles.
@/
fsm	
(fsm-id	"c_comments.lex",fsm-filename c_comments,fsm-namespace NS_c_comments
,fsm-class		Cc_comments {
   user-declaration
    public: 
    char ddd_[1024*32];
    int ddd_idx_;
    void copy_str_into_buffer(std::string* Str);
    void copy_kstr_into_buffer(const char* Str);
  ***
  user-implementation
    void Cc_comments::copy_str_into_buffer(std::string* Str){   
      const char* y = Str->c_str(); 
      int x(0);
      for(;y[x]!=0;++x,++ddd_idx_)ddd_[ddd_idx_] = y[x];
      ddd_[ddd_idx_] = 0;
    }
/@
@*3 |copy_kstr_into_buffer|.
@/
    void Cc_comments::copy_kstr_into_buffer(const char* Str){
      const char* y = Str; 
      int x(0);
      for(;y[x]!=0;++x,++ddd_idx_)ddd_[ddd_idx_] = y[x];
      ddd_[ddd_idx_] = 0;
   }
  ***
  constructor
    ddd_idx_ = 0;
    ddd_[ddd_idx_] = 0;
 ***
  op
    ddd_idx_ = 0;
    ddd_[ddd_idx_] = 0;
  ***
  }
,fsm-version "1.0",fsm-date "17 Juin 2003",fsm-debug "false"
,fsm-comments "C++ type comments lexer.")
parallel-parser	
(	
  parallel-thread-function
    TH_c_comments
  ***
  parallel-la-boundary
    eolr
  ***
)
@"/usr/local/yacco2/compiler/grammars/yacco2_T_includes.T"
rules{
Rc_comments  (
lhs {
    op
      Cc_comments* fsm = (Cc_comments*) rule_info__.parser__->fsm_tbl__;
      T_comment* com = new T_comment((const char*)&fsm->ddd_);
      com->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__);
      RSVP(com);
    ***
    }
){
  -> Rslash_asterisk |.| 
  -> R2slash |.|
} 

Rslash_asterisk  (){
  -> "/" "*" { 
    op
      Cc_comments* fsm = (Cc_comments*) rule_info__.parser__->fsm_tbl__;
        fsm->copy_kstr_into_buffer("/");// due to lex scanner
        fsm->copy_kstr_into_buffer("*");
loop:
	  switch (rule_info__.parser__->current_token()->enumerated_id__){
	  case T_Enum::T_raw_lf_: goto other;
	  case T_Enum::T_raw_cr_: goto cr;
	  case T_Enum::T_LR1_eog_: goto overrun;	
	  case T_Enum::T_raw_asteric_: goto aster;
          default: goto other;
          }
    cr:{// cr lf?
        fsm->copy_kstr_into_buffer(rule_info__.parser__->current_token()->id__);
         rule_info__.parser__->get_next_token();
        if(rule_info__.parser__->current_token()->enumerated_id__ 
            != T_Enum::T_raw_lf_) goto loop;// not cr lf
        fsm->copy_kstr_into_buffer(rule_info__.parser__->current_token()->id__);
        rule_info__.parser__->get_next_token();
goto loop;
    };
    aster:{ // end of k?
        fsm->copy_kstr_into_buffer(rule_info__.parser__->current_token()->id__);
          rule_info__.parser__->get_next_token();
        if(rule_info__.parser__->current_token()->enumerated_id__ 
            != T_Enum::T_raw_slash_) goto loop;// false eok
        fsm->copy_kstr_into_buffer(rule_info__.parser__->current_token()->id__);
          rule_info__.parser__->get_next_token();
        return;
    }
    overrun:{
      CAbs_lr1_sym* sym = new Err_comment_overrun;
      sym->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__);
      RSVP(sym);
      rule_info__.parser__->set_stop_parse(true);
      return;
    }
    other:{
        fsm->copy_kstr_into_buffer(rule_info__.parser__->current_token()->id__);
          rule_info__.parser__->get_next_token();
goto loop;
      }
    ***
    }
}

R2slash  (){
  -> "/" "/" { 
    op
      Cc_comments* fsm = (Cc_comments*) rule_info__.parser__->fsm_tbl__;
        fsm->copy_kstr_into_buffer("/");
        fsm->copy_kstr_into_buffer("/");
      for(;;){
	  switch (rule_info__.parser__->current_token()->enumerated_id__){
	  case T_Enum::T_raw_lf_: {
            return;
          }
	  case T_Enum::T_raw_cr_:{
            return;
          }
	  case T_Enum::T_LR1_eog_: return;	
          }
        fsm->copy_kstr_into_buffer(rule_info__.parser__->current_token()->id__);
          rule_info__.parser__->get_next_token();
      }
    ***
    }
}

}// end of rules
