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