/* Copyright Dave Bone 1998 - 2014 All Rights Reserved. No part of this document may be reproduced without written consent from the author. FILE: c_string.lex Dates: 17 Juin 2003 Purpose: c string recognizer : double quoted strings Eg. "hi" Returned: T_c_string Err_bad_eos - meta terminal indicating an improper end-of-string this occurs on eof,eog, or an eol terminal ending the string Err_bad_esc - bad escape sequence. Note: Stripped of its double quotes for ease of use */ /@ @i "/usr/local/yacco2/copyright.w" @** |c_string| Thread.\fbreak It recognizes double quoted c++ strings with embeded escape sequences. The double quoted sequence accepts 2 double " within the embeded character sequence without any conversion --- the 2nd " is not dropped. Escape sequences are just concatenated to the string. No conversion is done at present; just recognize the embeded character sequence. See comments in |angled_string| thread regarding badly terminated strings and escape sequences.\fbreak Returned data is the chacacter string without the bounding " quotes.\fbreak \fbreak Errors:\fbreak |Err_bad_esc| and |Err_bad_eos|.\fbreak \fbreak Returned T: |T_c_string|\fbreak @/ fsm (fsm-id "c_string.lex",fsm-filename c_string,fsm-namespace NS_c_string ,fsm-class Cc_string { user-prefix-declaration #include "esc_seq.h" *** 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_string::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_string::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 string lexer.") parallel-parser ( parallel-thread-function TH_c_string *** parallel-la-boundary eolr *** ) @"/usr/local/yacco2/compiler/grammars/yacco2_T_includes.T" rules{ Rc_string ( lhs{ op Cc_string* fsm = (Cc_string*) rule_info__.parser__->fsm_tbl__; CAbs_lr1_sym* sym = new T_c_string((const char*)&fsm->ddd_); sym->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__); RSVP(sym); *** } ) { -> Rquote |.| } Rquote (){ -> "\"" { /@ Caveat: Due to Mpost's literal not accepting an escape sequence for ", i substitute the " for char(34). It was my weak attempt to try to draw it. @/ op Cc_string* fsm = (Cc_string*) rule_info__.parser__->fsm_tbl__; loop: switch (rule_info__.parser__->current_token()->enumerated_id__){ case T_Enum::T_raw_lf_: goto overrun; case T_Enum::T_raw_cr_: goto overrun; case T_Enum::T_LR1_eog_: goto overrun; case T_Enum::T_raw_dbl_quote_: goto dblquote; case T_Enum::T_raw_back_slash_: goto escseq; default: goto other; } dblquote:{ // end of string rule_info__.parser__->get_next_token(); if(rule_info__.parser__->current_token()->enumerated_id__ == T_Enum::T_raw_dbl_quote_){ fsm->copy_kstr_into_buffer("\"");// due to lex scanner fsm->copy_kstr_into_buffer("\""); rule_info__.parser__->get_next_token(); goto loop; } return;// end of c string } overrun:{ CAbs_lr1_sym* sym = new Err_bad_eos; sym->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__); RSVP(sym); rule_info__.parser__->set_stop_parse(true); return; } escseq:{// what type of escape using namespace NS_esc_seq; Parser::parse_result result = rule_info__.parser__->start_manually_parallel_parsing(ITH_esc_seq.thd_id__); if(result == Parser::erred){ // in this case, it will not happen: here for education rule_info__.parser__->set_abort_parse(true); return; } // process returned token Caccept_parse& accept_parm = *rule_info__.parser__->arbitrated_token__; CAbs_lr1_sym* rtn_tok = accept_parm.accept_token__; int id = rtn_tok->enumerated_id__; accept_parm.accept_token__ = 0; if(id != T_Enum::T_T_esc_seq_) { RSVP(rtn_tok); return; } T_esc_seq* finc = (T_esc_seq*)(rtn_tok); fsm->copy_str_into_buffer(finc->esc_data()); rule_info__.parser__->override_current_token(*accept_parm.la_token__ ,accept_parm.la_token_pos__); delete finc; goto loop; }; other:{ fsm->copy_kstr_into_buffer(rule_info__.parser__->current_token()->id__); rule_info__.parser__->get_next_token(); goto loop; } *** } } }// end of rules