/* Copyright Dave Bone 1998 - 2014 All Rights Reserved. No part of this document may be reproduced without written consent from the author. FILE: c_literal.lex Dates: 17 Juin 2003 Purpose: c string recognizer : single quoted strings Eg. 'hi' Returned: T_c_literal 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 single quotes for ease of use */ /@ @i "/usr/local/yacco2/copyright.w" @** |c_literal| Thread.\fbreak It recognizes single quoted c++ literal strings with embeded escape sequences. The single quoted sequence accepts 2 single ' 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. Returned data is the chacacter string without the bounding single quotes.\fbreak \fbreak Errors:\fbreak |Err_bad_esc| and |Err_bad_eos|.\fbreak \fbreak Returned T: |T_literal|\fbreak @/ fsm (fsm-id "c_literal.lex",fsm-filename c_literal,fsm-namespace NS_c_literal ,fsm-class Cc_literal { 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_literal::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_literal::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 literal lexer.") parallel-parser ( parallel-thread-function TH_c_literal *** parallel-la-boundary eolr *** ) @"/usr/local/yacco2/compiler/grammars/yacco2_T_includes.T" // rules{ Rc_literal ( lhs{ op Cc_literal* fsm = (Cc_literal*) rule_info__.parser__->fsm_tbl__; CAbs_lr1_sym* sym = new T_c_literal((const char*)&fsm->ddd_); sym->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__); RSVP(sym); *** } ) { -> Rquote |.| } Rquote (){ -> "'" { op Cc_literal* fsm = (Cc_literal*) 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_right_quote_: goto rtquote; case T_Enum::T_raw_back_slash_: goto escseq; default: goto other; } rtquote:{ // end of literal? rule_info__.parser__->get_next_token(); if(rule_info__.parser__->current_token()->enumerated_id__ == T_Enum::T_raw_right_quote_){ fsm->copy_kstr_into_buffer("''"); rule_info__.parser__->get_next_token(); goto loop; } return;// end of literal } 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