]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/classic/test/tree_to_xml.cpp
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / classic / test / tree_to_xml.cpp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Copyright (c) 2001-2007 Hartmut Kaiser
20effc67 3 Copyright (c) 2020 Nikita Kniazev
7c673cae
FG
4 http://spirit.sourceforge.net/
5
6 Use, modification and distribution is subject to the Boost Software
7 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt)
9=============================================================================*/
10
7c673cae
FG
11#include <boost/preprocessor/cat.hpp>
12#include <boost/spirit/include/classic_core.hpp>
13#include <boost/spirit/include/classic_ast.hpp>
14#include <boost/spirit/include/classic_tree_to_xml.hpp>
15
1e59de90
TL
16#include <boost/core/lightweight_test.hpp>
17
7c673cae 18#include <iostream>
20effc67 19#include <iterator>
7c673cae 20#include <fstream>
20effc67 21#include <ostream>
7c673cae
FG
22#include <string>
23
24using namespace BOOST_SPIRIT_CLASSIC_NS;
25
26///////////////////////////////////////////////////////////////////////////////
27struct calculator : public grammar<calculator>
28{
29 static const int integerID = 1;
30 static const int factorID = 2;
31 static const int termID = 3;
32 static const int expressionID = 4;
33
34 template <typename ScannerT>
35 struct definition
36 {
37 definition(calculator const& /*self*/)
38 {
39 // Start grammar definition
40 integer = leaf_node_d[ lexeme_d[
41 (!ch_p('-') >> +digit_p)
42 ] ];
43
44 factor = integer
45 | inner_node_d[ch_p('(') >> expression >> ch_p(')')]
46 | (root_node_d[ch_p('-')] >> factor);
47
48 term = factor >>
49 *( (root_node_d[ch_p('*')] >> factor)
50 | (root_node_d[ch_p('/')] >> factor)
51 );
52
53 expression = term >>
54 *( (root_node_d[ch_p('+')] >> term)
55 | (root_node_d[ch_p('-')] >> term)
56 );
57 // End grammar definition
58
59 // turn on the debugging info.
60 BOOST_SPIRIT_DEBUG_RULE(integer);
61 BOOST_SPIRIT_DEBUG_RULE(factor);
62 BOOST_SPIRIT_DEBUG_RULE(term);
63 BOOST_SPIRIT_DEBUG_RULE(expression);
64 }
65
66 rule<ScannerT, parser_context<>, parser_tag<expressionID> > expression;
67 rule<ScannerT, parser_context<>, parser_tag<termID> > term;
68 rule<ScannerT, parser_context<>, parser_tag<factorID> > factor;
69 rule<ScannerT, parser_context<>, parser_tag<integerID> > integer;
70
71 rule<ScannerT, parser_context<>, parser_tag<expressionID> > const&
72 start() const { return expression; }
73 };
74};
75
76///////////////////////////////////////////////////////////////////////////////
20effc67
TL
77/// a streambuf implementation that sinks characters to output iterator
78template <typename OutputIterator, typename Char>
79struct psbuf : std::basic_streambuf<Char>
7c673cae 80{
20effc67
TL
81 template <typename T>
82 psbuf(T& sink) : sink_(sink) {}
83
84 // silence MSVC warning C4512: assignment operator could not be generated
85 BOOST_DELETED_FUNCTION(psbuf& operator=(psbuf const&))
86
87protected:
88 typename psbuf::int_type overflow(typename psbuf::int_type ch) BOOST_OVERRIDE
7c673cae 89 {
20effc67
TL
90 if (psbuf::traits_type::eq_int_type(ch, psbuf::traits_type::eof()))
91 return psbuf::traits_type::not_eof(ch);
92
93 *sink_ = psbuf::traits_type::to_char_type(ch);
94 ++sink_;
95 return ch;
7c673cae
FG
96 }
97
7c673cae 98private:
20effc67 99 OutputIterator sink_;
7c673cae
FG
100};
101
102///////////////////////////////////////////////////////////////////////////////
103#define EXPECTED_XML_OUTPUT "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n\
104<!DOCTYPE parsetree SYSTEM \"parsetree.dtd\">\n\
105<!-- 1+2 -->\n\
106<parsetree version=\"1.0\">\n\
107 <parsenode>\n\
108 <value>+</value>\n\
109 <parsenode>\n\
110 <value>1</value>\n\
111 </parsenode>\n\
112 <parsenode>\n\
113 <value>2</value>\n\
114 </parsenode>\n\
115 </parsenode>\n\
116</parsetree>\n"
117
118#define EXPECTED_XML_OUTPUT_WIDE BOOST_PP_CAT(L, EXPECTED_XML_OUTPUT)
119
120bool test(wchar_t const *text)
121{
122 typedef std::basic_string<wchar_t>::iterator iterator_t;
7c673cae
FG
123
124 std::basic_string<wchar_t> input(text);
125 calculator calc;
126 tree_parse_info<iterator_t> ast_info =
127 ast_parse(iterator_t(input.begin()), iterator_t(input.end()),
128 calc >> end_p, space_p);
129
130 std::basic_string<wchar_t> out;
131 {
20effc67
TL
132 psbuf<std::back_insert_iterator<std::wstring>, wchar_t> buf(out);
133 std::wostream outsink(&buf);
7c673cae
FG
134 basic_tree_to_xml<wchar_t>(outsink, ast_info.trees, input);
135 }
136 return out == EXPECTED_XML_OUTPUT_WIDE;
137}
138
139bool test(char const *text)
140{
141 typedef std::string::iterator iterator_t;
7c673cae
FG
142
143 std::string input(text);
144 calculator calc;
145 tree_parse_info<iterator_t> ast_info =
146 ast_parse(iterator_t(input.begin()), iterator_t(input.end()),
147 calc >> end_p, space_p);
148
149 std::string out;
150 {
20effc67
TL
151 psbuf<std::back_insert_iterator<std::string>, char> buf(out);
152 std::ostream outsink(&buf);
7c673cae
FG
153 basic_tree_to_xml<char>(outsink, ast_info.trees, input);
154 }
155 return out == EXPECTED_XML_OUTPUT;
156}
157
158int main()
159{
160 BOOST_TEST(test("1+2"));
161 if (std::has_facet<std::ctype<wchar_t> >(std::locale()))
162 {
163 BOOST_TEST(test(L"1+2"));
164 }
165 return boost::report_errors();
166}