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
15namespace 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
26 error_handler(BaseIterator first, BaseIterator last)
27 : first(first), last(last) {}
28
29 template <typename Message, typename What>
30 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
40 int line;
41 BaseIterator line_start = get_pos(err_pos: err_pos_base, line);
42 if (err_pos_base != last)
43 {
44 std::cout << message << what << " line " << line << ':' << std::endl;
45 std::cout << get_line(err_pos: line_start) << std::endl;
46 for (; line_start != err_pos_base; ++line_start)
47 std::cout << ' ';
48 std::cout << '^' << std::endl;
49 }
50 else
51 {
52 std::cout << "Unexpected end of file. ";
53 std::cout << message << what << " line " << line << std::endl;
54 }
55 }
56
57 BaseIterator get_pos(BaseIterator err_pos, int& line) const
58 {
59 line = 1;
60 BaseIterator i = first;
61 BaseIterator line_start = first;
62 while (i != err_pos)
63 {
64 bool eol = false;
65 if (i != err_pos && *i == '\r') // CR
66 {
67 eol = true;
68 line_start = ++i;
69 }
70 if (i != err_pos && *i == '\n') // LF
71 {
72 eol = true;
73 line_start = ++i;
74 }
75 if (eol)
76 ++line;
77 else
78 ++i;
79 }
80 return line_start;
81 }
82
83 std::string get_line(BaseIterator err_pos) const
84 {
85 BaseIterator i = err_pos;
86 // position i to the next EOL
87 while (i != last && (*i != '\r' && *i != '\n'))
88 ++i;
89 return std::string(err_pos, i);
90 }
91
92 BaseIterator first;
93 BaseIterator last;
94 std::vector<Iterator> iters;
95 };
96}
97
98#endif
99
100

source code of boost/libs/spirit/example/qi/compiler_tutorial/conjure3/error_handler.hpp