error_handler.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2001-2011 Hartmut Kaiser
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. #if !defined(BOOST_SPIRIT_CONJURE_ERROR_HANDLER_HPP)
  8. #define BOOST_SPIRIT_CONJURE_ERROR_HANDLER_HPP
  9. #include <iostream>
  10. #include <string>
  11. #include <vector>
  12. namespace client
  13. {
  14. ///////////////////////////////////////////////////////////////////////////////
  15. // The error handler
  16. ///////////////////////////////////////////////////////////////////////////////
  17. template <typename BaseIterator, typename Iterator>
  18. struct error_handler
  19. {
  20. template <typename, typename, typename>
  21. struct result { typedef void type; };
  22. error_handler(BaseIterator first, BaseIterator last)
  23. : first(first), last(last) {}
  24. template <typename Message, typename What>
  25. void operator()(
  26. Message const& message,
  27. What const& what,
  28. Iterator err_pos) const
  29. {
  30. // retrieve underlying iterator from current token, err_pos points
  31. // to the last validly matched token, so we use its end iterator
  32. // as the error position
  33. BaseIterator err_pos_base = err_pos->matched().end();
  34. int line;
  35. BaseIterator line_start = get_pos(err_pos_base, line);
  36. if (err_pos_base != last)
  37. {
  38. std::cout << message << what << " line " << line << ':' << std::endl;
  39. std::cout << get_line(line_start) << std::endl;
  40. for (; line_start != err_pos_base; ++line_start)
  41. std::cout << ' ';
  42. std::cout << '^' << std::endl;
  43. }
  44. else
  45. {
  46. std::cout << "Unexpected end of file. ";
  47. std::cout << message << what << " line " << line << std::endl;
  48. }
  49. }
  50. BaseIterator get_pos(BaseIterator err_pos, int& line) const
  51. {
  52. line = 1;
  53. BaseIterator i = first;
  54. BaseIterator line_start = first;
  55. while (i != err_pos)
  56. {
  57. bool eol = false;
  58. if (i != err_pos && *i == '\r') // CR
  59. {
  60. eol = true;
  61. line_start = ++i;
  62. }
  63. if (i != err_pos && *i == '\n') // LF
  64. {
  65. eol = true;
  66. line_start = ++i;
  67. }
  68. if (eol)
  69. ++line;
  70. else
  71. ++i;
  72. }
  73. return line_start;
  74. }
  75. std::string get_line(BaseIterator err_pos) const
  76. {
  77. BaseIterator i = err_pos;
  78. // position i to the next EOL
  79. while (i != last && (*i != '\r' && *i != '\n'))
  80. ++i;
  81. return std::string(err_pos, i);
  82. }
  83. BaseIterator first;
  84. BaseIterator last;
  85. std::vector<Iterator> iters;
  86. };
  87. }
  88. #endif