fork download
  1. //#include <boost/config/warning_disable.hpp>
  2. //#define BOOST_SPIRIT_DEBUG_PRINT_SOME 80
  3. //#define BOOST_SPIRIT_DEBUG // before including Spirit
  4. #include <boost/spirit/include/lex_lexertl.hpp>
  5. #include <boost/spirit/include/qi.hpp>
  6. #include <fstream>
  7. #ifdef MEMORY_MAPPED
  8. # include <boost/iostreams/device/mapped_file.hpp>
  9. #endif
  10. //#include <boost/spirit/include/lex_generate_static_lexertl.hpp>
  11.  
  12. namespace /*anon*/
  13. {
  14. namespace phx=boost::phoenix;
  15. namespace qi =boost::spirit::qi;
  16. namespace lex=boost::spirit::lex;
  17.  
  18. static bool undoublequote(std::string& val)
  19. {
  20. auto outidx = 0;
  21. for(auto in = val.begin(); in!=val.end(); ++in) {
  22. switch(*in) {
  23. case '"':
  24. if (++in == val.end()) { // eat the escape
  25. // end of input reached
  26. val.resize(outidx); // resize to effective chars
  27. return true;
  28. }
  29. // fall through
  30. default:
  31. val[outidx++] = *in; // append the character
  32. }
  33. }
  34.  
  35. return false; // not ended with double quote as expected
  36. }
  37.  
  38. template <typename Lexer>
  39. struct mylexer_t : lex::lexer<Lexer>
  40. {
  41. struct undoublequote_lex_type {
  42. template <typename, typename, typename, typename> struct result { typedef void type; };
  43.  
  44. template <typename It, typename IdType, typename pass_flag, typename Ctx>
  45. void operator()(It& f, It& l, pass_flag& pass, IdType& id, Ctx& ctx) const {
  46. std::string raw(f,l);
  47. if (undoublequote(raw))
  48. ctx.set_value(raw);
  49. else
  50. pass = lex::pass_flags::pass_fail;
  51. }
  52. } undoublequote_lex;
  53.  
  54. mylexer_t()
  55. {
  56. string_quote_double = "\\\"([^\"]|\\\"\\\")*\\\"";
  57.  
  58. const static undoublequote_lex_type undoublequote_lex;
  59. this->self("INITIAL")
  60. = string_quote_double [ undoublequote_lex ]
  61. | lex::token_def<>("[ \t\r\n]") [ lex::_pass = lex::pass_flags::pass_ignore ]
  62. ;
  63. }
  64.  
  65. lex::token_def<std::string> string_quote_double;
  66. };
  67.  
  68. template <typename Iterator> struct mygrammar_t
  69. : public qi::grammar<Iterator, std::vector<std::string>()>
  70. {
  71. typedef mygrammar_t<Iterator> This;
  72.  
  73. template <typename TokenDef>
  74. mygrammar_t(TokenDef const& tok) : mygrammar_t::base_type(start)
  75. {
  76. using namespace qi;
  77.  
  78. string_quote_double = tok.string_quote_double;
  79. start = *string_quote_double;
  80.  
  81. BOOST_SPIRIT_DEBUG_NODES((start)(string_quote_double));
  82. }
  83.  
  84. private:
  85. qi::rule<Iterator, std::vector<std::string>()> start;
  86. qi::rule<Iterator, std::string()> string_quote_double;
  87. };
  88. }
  89.  
  90. std::vector<std::string> do_test_parse(const std::string& v)
  91. {
  92. char const *first = &v[0];
  93. char const *last = first+v.size();
  94.  
  95. typedef lex::lexertl::token<char const*, boost::mpl::vector<char, std::string> > token_type;
  96. typedef lex::lexertl::actor_lexer<token_type> lexer_type;
  97.  
  98. typedef mylexer_t<lexer_type>::iterator_type iterator_type;
  99. const static mylexer_t<lexer_type> mylexer;
  100. const static mygrammar_t<iterator_type> parser(mylexer);
  101.  
  102. auto iter = mylexer.begin(first, last);
  103. auto end = mylexer.end();
  104.  
  105. std::vector<std::string> data;
  106. bool r = qi::parse(iter, end, parser, data);
  107.  
  108. r = r && (iter == end);
  109.  
  110. if (!r)
  111. std::cerr << "parsing (" << iter->state() << ") failed at: '" << std::string(first, last) << "'\n";
  112.  
  113. return data;
  114. }
  115.  
  116. int main(int argc, const char *argv[])
  117. {
  118. for (auto&& s : do_test_parse( "\"bla\"\"blo\""))
  119. std::cout << s << std::endl;
  120. }
  121.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:4:48: fatal error: boost/spirit/include/lex_lexertl.hpp: No such file or directory
compilation terminated.
stdout
Standard output is empty