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