error_handler.cpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. /*=============================================================================
  2. Copyright (c) 2001-2015 Joel de Guzman
  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 <boost/detail/lightweight_test.hpp>
  7. #include <boost/spirit/home/x3.hpp>
  8. #include <boost/spirit/home/x3/support/utility/annotate_on_success.hpp>
  9. #include <string>
  10. #include <sstream>
  11. namespace x3 = boost::spirit::x3;
  12. struct error_handler_base
  13. {
  14. template <typename Iterator, typename Exception, typename Context>
  15. x3::error_handler_result on_error(
  16. Iterator&, Iterator const&
  17. , Exception const& x, Context const& context) const
  18. {
  19. std::string message = "Error! Expecting: " + x.which() + " here:";
  20. auto& error_handler = x3::get<x3::error_handler_tag>(context).get();
  21. error_handler(x.where(), message);
  22. return x3::error_handler_result::fail;
  23. }
  24. };
  25. struct test_rule_class : x3::annotate_on_success, error_handler_base {};
  26. x3::rule<test_rule_class> const test_rule;
  27. auto const test_rule_def = x3::lit("foo") > x3::lit("bar") > x3::lit("git");
  28. BOOST_SPIRIT_DEFINE(test_rule)
  29. void test(std::string const& line_break) {
  30. std::string const input("foo" + line_break + " foo" + line_break + "git");
  31. auto const begin = std::begin(input);
  32. auto const end = std::end(input);
  33. std::stringstream stream;
  34. x3::error_handler<std::string::const_iterator> error_handler{begin, end, stream};
  35. auto const parser = x3::with<x3::error_handler_tag>(std::ref(error_handler))[test_rule];
  36. x3::phrase_parse(begin, end, parser, x3::space);
  37. BOOST_TEST_EQ(stream.str(), "In line 2:\nError! Expecting: \"bar\" here:\n foo\n__^_\n");
  38. }
  39. int main() {
  40. test("\n");
  41. test("\r");
  42. test("\r\n");
  43. return boost::report_errors();
  44. }