expect.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*=============================================================================
  2. Copyright (c) 2016 Frank Hein, maxence business consulting gmbh
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #include <iostream>
  7. #include <map>
  8. #include <boost/spirit/home/qi.hpp>
  9. #include <boost/spirit/home/qi/nonterminal/grammar.hpp>
  10. #include <boost/spirit/include/phoenix.hpp>
  11. #include <boost/foreach.hpp>
  12. namespace qi = boost::spirit::qi;
  13. typedef std::string::const_iterator iterator_type;
  14. typedef std::string result_type;
  15. template<typename Parser>
  16. void parse(const std::string message, const std::string& input, const std::string& rule, const Parser& parser) {
  17. iterator_type iter = input.begin(), end = input.end();
  18. std::vector<result_type> parsed_result;
  19. std::cout << "-------------------------\n";
  20. std::cout << message << "\n";
  21. std::cout << "Rule: " << rule << std::endl;
  22. std::cout << "Parsing: \"" << input << "\"\n";
  23. bool result = qi::phrase_parse(iter, end, parser, qi::space, parsed_result);
  24. if (result)
  25. {
  26. std::cout << "Parser succeeded.\n";
  27. std::cout << "Parsed " << parsed_result.size() << " elements:";
  28. BOOST_FOREACH(result_type const& str, parsed_result)
  29. {
  30. std::cout << "[" << str << "]";
  31. }
  32. std::cout << std::endl;
  33. }
  34. else
  35. {
  36. std::cout << "Parser failed" << std::endl;
  37. }
  38. if (iter == end) {
  39. std::cout << "EOI reached." << std::endl;
  40. }
  41. else {
  42. std::cout << "EOI not reached. Unparsed: \"" << std::string(iter, end) << "\"" << std::endl;
  43. }
  44. std::cout << "-------------------------\n";
  45. }
  46. namespace grammars {
  47. namespace phx = boost::phoenix;
  48. template <typename Iterator>
  49. struct ident : qi::grammar < Iterator, std::string(), qi::space_type>
  50. {
  51. ident();
  52. qi::rule <iterator_type, std::string(), qi::space_type>
  53. id, id_list, qualified_id;
  54. };
  55. template <typename Iterator>
  56. ident<Iterator>::ident() : ident::base_type(id_list) {
  57. using qi::on_error;
  58. using qi::fail;
  59. using qi::expect;
  60. id = (qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_'));
  61. id_list = expect[id >> qi::lit(';')];
  62. on_error<fail>(id_list,
  63. phx::ref(std::cout)
  64. << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl
  65. << "Error! Expecting "
  66. << qi::_4
  67. << " here: "
  68. << phx::construct<std::string>(qi::_3, qi::_2) << std::endl
  69. << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl
  70. );
  71. }
  72. }
  73. int main() {
  74. grammars::ident<iterator_type> id;
  75. parse("expect directive, fail on first"
  76. , "1234; id2;"
  77. , "qi::expect[ id >> qi::lit(';') ]"
  78. , id);
  79. parse("expect directive, fail on second"
  80. , "id1, id2"
  81. , "qi::expect[ id >> qi::lit(';') ]"
  82. , id);
  83. parse("expect directive, success"
  84. , "id1;"
  85. , "qi::expect[ id >> qi::lit(';') ]"
  86. , id);
  87. return 0;
  88. }