/*
  Copyright Dave Bone 1998 - 2014 
  All Rights Reserved. 
  No part of this document may be reproduced without written consent from the author.
	
FILE:       cweb_or_c_k.lex
Dates:      10 Feb. 2008
*/
/@
@i "/usr/local/yacco2/copyright.w"
@** |cweb_or_c_k|  combined ``c++ '' or my ``cweb'' comment Thread.\fbreak
Why? To eliminate the non-determinism 
between these 2 threads due to their common prefix: ``/''.
Why again? Speed and stop the confusion across the threads address space
when called by procedure instead of by thread. The thread gets called singlely
and hence the speed versus parallel threads competing where only one will win.
Some interesting debuging issues where found when using 
Sun's superb ``mdb'' and ``dtrace'' tools.
@*2 Cpp comments.\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.
@*2 Cweb type comments.\fbreak
Recognize |cweb| comments buried within a grammar.
These comments start with ``/@@''
followed by the comments
and closed off by ``@@'' and a forward slash --- can't declare
it as this will prematurely end this comment.
The enclosing comment prefix / suffix are not appended to the data
as only its contents that are outputed in the various documents.

Note: Use of the \invisibleshift{} symbol to lower the Lookahead set members.
@/
fsm	
(fsm-id	"cweb_or_c_k.lex",fsm-filename cweb_or_c_k,fsm-namespace NS_cweb_or_c_k
,fsm-class		Ccweb_or_c_k {
   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 Ccweb_or_c_k::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 Ccweb_or_c_k::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 "10 feb. 2008",fsm-debug "false"
,fsm-comments "C++ or cweb type comments lexer.")
parallel-parser	
(	
  parallel-thread-function
    TH_cweb_or_c_k
  ***
  parallel-la-boundary
    eolr
  ***
)
@"/usr/local/yacco2/compiler/grammars/yacco2_T_includes.T"
rules{
Rcweb_or_c_k  (){
  -> Rslash_asterisk |.| {
  op
      Ccweb_or_c_k* fsm = (Ccweb_or_c_k*) 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);
  
  ***
  }
  -> R2slash |.| {
  op
      Ccweb_or_c_k* fsm = (Ccweb_or_c_k*) 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_at |.| {
  op
      Ccweb_or_c_k* fsm = (Ccweb_or_c_k*) rule_info__.parser__->fsm_tbl__;
      T_cweb_comment* com = new T_cweb_comment((const char*)&fsm->ddd_);
      com->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__);// file marker
      RSVP(com);
  
  ***
  }
} 
Rslash_at (){
  -> "/" "@" {// exclude the /@ and @/ from cweb comment
  op
      Ccweb_or_c_k* fsm = (Ccweb_or_c_k*) rule_info__.parser__->fsm_tbl__;
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_at_sign_: goto atsign;
          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;
    };
    atsign:{ // end of k?
          rule_info__.parser__->get_next_token();
        if(rule_info__.parser__->current_token()->enumerated_id__ 
            != T_Enum::T_raw_slash_){
        fsm->copy_kstr_into_buffer("@");
            goto loop;// false eok
        }
        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;
      }
  ***
  }
}

Rslash_asterisk  (){
  -> "/" "*" { 
    op
      Ccweb_or_c_k* fsm = (Ccweb_or_c_k*) 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
      Ccweb_or_c_k* fsm = (Ccweb_or_c_k*) 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
