Ticket #9737: test-boost.cpp

File test-boost.cpp, 3.2 KB (added by Julien Charbon <jcharbon@…>, 9 years ago)

Simple test case example

Line 
1// A parser for a comma separated list of numbers,
2// with positional error reporting
3
4#include <boost/spirit/include/classic_core.hpp>
5#include <boost/spirit/include/classic_position_iterator.hpp>
6#include <boost/spirit/include/classic_functor_parser.hpp>
7#include "boost/spirit/include/classic_multi_pass.hpp"
8#include <iostream>
9#include <fstream>
10#include <sstream>
11#include <vector>
12
13using namespace std;
14using namespace BOOST_SPIRIT_CLASSIC_NS;
15
16std::ostream & operator<<(std::ostream & out, file_position const & lc) {
17
18 return out << "\nFile:\t" << lc.file
19 << "\nLine:\t" << lc.line
20 << "\nCol:\t" << lc.column << endl;
21}
22
23struct error_report_parser {
24
25 char const * eol_msg;
26 char const * msg;
27
28 error_report_parser(char const * eol_msg_, char const * msg_) :
29 eol_msg(eol_msg_),
30 msg (msg_) {
31 }
32
33 typedef nil_t result_t;
34
35 template <typename ScannerT>
36 int operator()(ScannerT const& scan, result_t& /*result*/) const {
37
38 if (scan.at_end()) {
39 if (eol_msg) {
40 file_position fpos = scan.first.get_position();
41 cerr << fpos << eol_msg << endl;
42 }
43 } else {
44 if (msg) {
45 file_position fpos = scan.first.get_position();
46 cerr << fpos << msg << endl;
47 }
48 }
49
50 return -1; // Fail.
51 }
52};
53
54typedef functor_parser<error_report_parser> error_report_p;
55
56error_report_p
57error_badnumber_or_eol =
58 error_report_parser(
59 "Expecting a number, but found the end of the file\n",
60 "Expecting a number, but found something else\n"
61 );
62
63error_report_p
64error_badnumber =
65 error_report_parser(
66 0,
67 "Expecting a number, but found something else\n"
68 );
69
70error_report_p
71error_comma =
72 error_report_parser(
73 0,
74 "Expecting a comma, but found something else\n"
75 );
76
77bool parse_numbers(istream & istr, vector<double> & v) {
78
79 typedef multi_pass<istreambuf_iterator<char> > multi_pass_stream_iterator;
80 typedef position_iterator<multi_pass_stream_iterator> position_stream_iterator;
81
82 multi_pass_stream_iterator multi_begin(
83 make_multi_pass(istreambuf_iterator<char>(istr)));
84
85 multi_pass_stream_iterator multi_end(
86 make_multi_pass(istreambuf_iterator<char>()));
87
88 position_stream_iterator pos_begin(multi_begin, multi_end, "internal string");
89 position_stream_iterator pos_end;
90
91 pos_begin.set_tabchars(8);
92 return parse(pos_begin, pos_end,
93
94 // Begin grammar
95 (
96 (real_p[push_back_a(v)] | error_badnumber)
97 >> *(
98 (',' | error_comma)
99 >> (real_p[push_back_a(v)] | error_badnumber_or_eol)
100 )
101 )
102 ,
103 // End grammar
104
105 space_p).full;
106}
107
108int main(int argc, char **argv) {
109
110 istringstream itest("0, 1, 2");
111
112 vector<double> v;
113 if (parse_numbers(itest, v)) {
114
115 cout << "Parsing:\n";
116 cout << itest.str() << "\nParses OK: " << endl;
117
118 for (vector<double>::size_type i = 0; i < v.size(); ++i)
119 cout << i << ": " << v[i] << endl;
120
121 } else {
122
123 cout << "Parsing failed\n";
124 }
125
126 return 0;
127}