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