/* Copyright Dave Bone 1998 - 2014 All Rights Reserved. No part of this document may be reproduced without written consent from the author. FILE: o2_sdc.lex dates: 3 Jan.2003 Purpose: Extract yacco2's syntax directed code conduit: syntax_code errors: Err_no_end_of_code Err_comment_overrun Err_bad_eos Err_bad_esc Err_no_syntax_code_present Note: A simple test is done as to whether there is any real syntax directed code is inputted: only strings, literals, or chrs (not {eol, ws}) are considered code. Due to the overhead of strings and their copy facility, I've changed to the raw string copy with a fixed buffer size. The saftey and flexibility had too much cost to run: approximately 10 seconds of overhead on approximately 100k of text. Looking at the way the string was grown out when characters were appended to it demanded that I use this approach. */ /@ @i "/usr/local/yacco2/copyright.w" @** |o2_sdc| Thread.\fbreak A single crawler of characters scooping up a grammar directive's syntax directed code. Added to it is ``cweb'' comment support. This allows the grammar document to support better code formatting particularly when the ``syntax directed code'' is big. The caveat is the emitted cpp code when ``-p'' option is on contains the ``cweave'' formatting directives and bypassed when not to generate the grammar document. So be warned. Generate the cpp code without the ``-p'' option to avoid the c++ errors. @/ fsm (fsm-id "o2_sdc.lex",fsm-filename o2_sdc,fsm-namespace NS_o2_sdc ,fsm-class Co2_sdc{ user-prefix-declaration #include "cweb_or_c_k.h" #include "c_string.h" #include "c_literal.h" #include "o2_code_end.h" extern char PRT_SW; *** 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 Co2_sdc::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 Co2_sdc::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; parser__->set_use_all_shift_on(); CAbs_lr1_sym* sym = parser__->start_token__; switch (sym->enumerated_id__){ case T_Enum::T_LR1_eog_: break; default: return; } parser__->set_use_all_shift_off(); *** } ,fsm-version "1.0",fsm-date "30 dec 2002",fsm-debug "false" ,fsm-comments "\\O2's syntax directed code extractor.") parallel-parser ( parallel-thread-function TH_o2_sdc *** parallel-la-boundary eolr - |+| - ||| *** ) @"/usr/local/yacco2/compiler/grammars/yacco2_T_includes.T" rules{ Ryacco2_syntax_code ( lhs{ op Co2_sdc* fsm = (Co2_sdc*)rule_info__.parser__->fsm_tbl__; CAbs_lr1_sym* sym(0); if(fsm->ddd_idx_ == 0){ sym = new Err_no_syntax_code_present; sym->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__); RSVP(sym); rule_info__.parser__->set_stop_parse(true); return; } sym = new T_syntax_code((const char*)&fsm->ddd_); sym->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__); RSVP(sym); *** } ){ -> Rchrs } Rchrs (){ -> Rchr -> Rchrs Rchr } Rchr ( lhs { op if(rule_info__.parser__->stop_parse__ == true) return; CAbs_lr1_sym* la_sym = rule_info__.parser__->current_token(); using namespace NS_yacco2_T_enum; using namespace NS_yacco2_terminals; // watch for overrun if(la_sym->enumerated_id__ == T_Enum::T_LR1_eog_){ CAbs_lr1_sym* sym = new Err_no_end_of_code; sym->set_rc(*la_sym,__FILE__,__LINE__); RSVP(sym); rule_info__.parser__->set_stop_parse(true); } *** } ){ -> ||| "comment" NS_cweb_or_c_k::TH_cweb_or_c_k { op Co2_sdc* fsm = (Co2_sdc*)rule_info__.parser__->fsm_tbl__; T_comment* k = sf->p2__; k->set_auto_delete(true);// delete it when it pops from stack fsm->copy_str_into_buffer(k->comment_data()); *** } -> ||| "cweb-comment" NULL { op Co2_sdc* fsm = (Co2_sdc*)rule_info__.parser__->fsm_tbl__; T_cweb_comment* k = sf->p2__; k->set_auto_delete(true);// delete it when it pops from stack if(PRT_SW == 'n') return;// bypass the cweve comments in the cpp code fsm->copy_str_into_buffer(k->comment_data()); string fmt("@+=\n"); fsm->copy_str_into_buffer(&fmt); *** } -> ||| "c-string" NS_c_string::TH_c_string{ op Co2_sdc* fsm = (Co2_sdc*)rule_info__.parser__->fsm_tbl__; T_c_string* k = sf->p2__; k->set_auto_delete(true);// delete it when it pops from stack // add back the bounding double quotes fsm->ddd_[fsm->ddd_idx_] = '"'; ++fsm->ddd_idx_; fsm->copy_str_into_buffer(k->c_string()); fsm->ddd_[fsm->ddd_idx_] = '"'; ++fsm->ddd_idx_; fsm->ddd_[fsm->ddd_idx_] = 0; *** } -> ||| "c-literal" NS_c_literal::TH_c_literal{ op Co2_sdc* fsm = (Co2_sdc*)rule_info__.parser__->fsm_tbl__; T_c_literal* k = sf->p2__; k->set_auto_delete(true); // add back the bounding single quotes fsm->ddd_[fsm->ddd_idx_] = '\''; ++fsm->ddd_idx_; fsm->copy_str_into_buffer(k->c_literal()); fsm->ddd_[fsm->ddd_idx_] = '\''; ++fsm->ddd_idx_; fsm->ddd_[fsm->ddd_idx_] = 0; *** } -> ||| "#***" NS_o2_code_end::TH_o2_code_end{ op sf->p2__->set_auto_delete(true); rule_info__.parser__->set_use_all_shift_off(); *** } -> |+| { /@ Add balance of characters to sdcode string: ex. comma. Special escape sequences are put back to their original declaration. @/ op Co2_sdc* fsm = (Co2_sdc*)rule_info__.parser__->fsm_tbl__; CAbs_lr1_sym* k = sf->p1__; switch (k->enumerated_id__){ case T_Enum::T_LR1_eog_:{ rule_info__.parser__->set_use_all_shift_off(); break; } case T_Enum::T_T_eol_:{ fsm->copy_kstr_into_buffer("\n"); break; } case T_Enum::T_raw_sp_:{ fsm->copy_kstr_into_buffer(" "); break; } case T_Enum::T_raw_ff_:{ fsm->copy_kstr_into_buffer("\f"); break; } case T_Enum::T_raw_vt_:{ fsm->copy_kstr_into_buffer("\v"); break; } case T_Enum::T_raw_ht_:{ fsm->copy_kstr_into_buffer("\t"); break; } default:{ fsm->ddd_[fsm->ddd_idx_] = k->id__[0]; ++fsm->ddd_idx_; fsm->ddd_[fsm->ddd_idx_] = 0; } } *** } -> ||| |?| NULL {// errors op RSVP(sf->p2__); rule_info__.parser__->set_stop_parse(true); *** } } }// end of rules