]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / classic / example / fundamental / position_iterator / position_iterator.cpp
1 /*=============================================================================
2 Copyright (c) 2002 Juan Carlos Arevalo-Baeza
3 http://spirit.sourceforge.net/
4
5 Use, modification and distribution is subject to the Boost Software
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 ///////////////////////////////////////////////////////////////////////////////
10 //
11 // A parser for a comma separated list of numbers,
12 // with positional error reporting
13 // See the "Position Iterator" chapter in the User's Guide.
14 //
15 // [ JCAB 9/28/2002 ]
16 //
17 ///////////////////////////////////////////////////////////////////////////////
18 #include <boost/spirit/include/classic_core.hpp>
19 #include <boost/spirit/include/classic_position_iterator.hpp>
20 #include <boost/spirit/include/classic_functor_parser.hpp>
21 #include <iostream>
22 #include <fstream>
23 #include <vector>
24
25 ///////////////////////////////////////////////////////////////////////////////
26 using namespace std;
27 using namespace BOOST_SPIRIT_CLASSIC_NS;
28
29 ///////////////////////////////////////////////////////////////////////////////
30 //
31 // Our error reporting parsers
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 std::ostream& operator<<(std::ostream& out, file_position const& lc)
35 {
36 return out <<
37 "\nFile:\t" << lc.file <<
38 "\nLine:\t" << lc.line <<
39 "\nCol:\t" << lc.column << endl;
40 }
41
42 struct error_report_parser {
43 char const* eol_msg;
44 char const* msg;
45
46 error_report_parser(char const* eol_msg_, char const* msg_):
47 eol_msg(eol_msg_),
48 msg (msg_)
49 {}
50
51 typedef nil_t result_t;
52
53 template <typename ScannerT>
54 int
55 operator()(ScannerT const& scan, result_t& /*result*/) const
56 {
57 if (scan.at_end()) {
58 if (eol_msg) {
59 file_position fpos = scan.first.get_position();
60 cerr << fpos << eol_msg << endl;
61 }
62 } else {
63 if (msg) {
64 file_position fpos = scan.first.get_position();
65 cerr << fpos << msg << endl;
66 }
67 }
68
69 return -1; // Fail.
70 }
71
72 };
73 typedef functor_parser<error_report_parser> error_report_p;
74
75 error_report_p
76 error_badnumber_or_eol =
77 error_report_parser(
78 "Expecting a number, but found the end of the file\n",
79 "Expecting a number, but found something else\n"
80 );
81
82 error_report_p
83 error_badnumber =
84 error_report_parser(
85 0,
86 "Expecting a number, but found something else\n"
87 );
88
89 error_report_p
90 error_comma =
91 error_report_parser(
92 0,
93 "Expecting a comma, but found something else\n"
94 );
95
96 ///////////////////////////////////////////////////////////////////////////////
97 //
98 // Our comma separated list parser
99 //
100 ///////////////////////////////////////////////////////////////////////////////
101 bool
102 parse_numbers(char const* filename, char const* str, vector<double>& v)
103 {
104 typedef position_iterator<char const*> iterator_t;
105 iterator_t begin(str, str + strlen(str), filename);
106 iterator_t end;
107 begin.set_tabchars(8);
108 return parse(begin, end,
109
110 // Begin grammar
111 (
112 (real_p[push_back_a(v)] | error_badnumber)
113 >> *(
114 (',' | error_comma)
115 >> (real_p[push_back_a(v)] | error_badnumber_or_eol)
116 )
117 )
118 ,
119 // End grammar
120
121 space_p).full;
122 }
123
124 ////////////////////////////////////////////////////////////////////////////
125 //
126 // Main program
127 //
128 ////////////////////////////////////////////////////////////////////////////
129 int
130 main(int argc, char **argv)
131 {
132 cout << "/////////////////////////////////////////////////////////\n\n";
133 cout << "\tAn error-reporting parser for Spirit...\n\n";
134 cout << "Parses a comma separated list of numbers from a file.\n";
135 cout << "The numbers will be inserted in a vector of numbers\n\n";
136 cout << "/////////////////////////////////////////////////////////\n\n";
137
138 char str[65536];
139 char const* filename;
140
141 if (argc > 1) {
142 filename = argv[1];
143 ifstream file(filename);
144 file.get(str, sizeof(str), '\0');
145 } else {
146 filename = "<cin>";
147 cin.get(str, sizeof(str), '\0');
148 }
149
150 vector<double> v;
151 if (parse_numbers(filename, str, v))
152 {
153 cout << "-------------------------\n";
154 cout << "Parsing succeeded\n";
155 cout << str << " Parses OK: " << endl;
156
157 for (vector<double>::size_type i = 0; i < v.size(); ++i)
158 cout << i << ": " << v[i] << endl;
159
160 cout << "-------------------------\n";
161 }
162 else
163 {
164 cout << "-------------------------\n";
165 cout << "Parsing failed\n";
166 cout << "-------------------------\n";
167 }
168
169 cout << "Bye... :-) \n\n";
170 return 0;
171 }
172
173