]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/quickbook/src/doc_info_grammar.cpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / tools / quickbook / src / doc_info_grammar.cpp
1 /*=============================================================================
2 Copyright (c) 2002 2004 2006 Joel de Guzman
3 Copyright (c) 2004 Eric Niebler
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 <map>
12 #include <boost/foreach.hpp>
13 #include <boost/spirit/include/classic_chset.hpp>
14 #include <boost/spirit/include/classic_core.hpp>
15 #include <boost/spirit/include/classic_loops.hpp>
16 #include <boost/spirit/include/classic_numerics.hpp>
17 #include <boost/spirit/include/classic_symbols.hpp>
18 #include <boost/spirit/include/phoenix1_operators.hpp>
19 #include <boost/spirit/include/phoenix1_primitives.hpp>
20 #include "actions.hpp"
21 #include "doc_info_tags.hpp"
22 #include "grammar_impl.hpp"
23 #include "phrase_tags.hpp"
24 #include "state.hpp"
25
26 namespace quickbook
27 {
28 namespace cl = boost::spirit::classic;
29
30 struct attribute_info
31 {
32 attribute_info(value::tag_type t, cl::rule<scanner>* r)
33 : tag(t), rule(r)
34 {
35 }
36
37 value::tag_type tag;
38 cl::rule<scanner>* rule;
39 };
40
41 struct doc_info_grammar_local
42 {
43 struct assign_attribute_type
44 {
45 assign_attribute_type(doc_info_grammar_local& l_) : l(l_) {}
46
47 void operator()(value::tag_type& t) const
48 {
49 l.attribute_rule = *l.attribute_rules[t];
50 l.attribute_tag = t;
51 }
52
53 doc_info_grammar_local& l;
54 };
55
56 struct fallback_attribute_type
57 {
58 fallback_attribute_type(doc_info_grammar_local& l_) : l(l_) {}
59
60 void operator()(parse_iterator, parse_iterator) const
61 {
62 l.attribute_rule = l.doc_fallback;
63 l.attribute_tag = value::default_tag;
64 }
65
66 doc_info_grammar_local& l;
67 };
68
69 cl::rule<scanner> doc_info_block, doc_attribute, doc_info_attribute,
70 doc_info_escaped_attributes, doc_title, doc_simple, doc_phrase,
71 doc_fallback, doc_authors, doc_author, doc_copyright,
72 doc_copyright_holder, doc_source_mode, doc_biblioid,
73 doc_compatibility_mode, quickbook_version, macro, char_;
74 cl::uint_parser<int, 10, 4, 4> doc_copyright_year;
75 cl::symbols<> doc_types;
76 cl::symbols<value::tag_type> doc_info_attributes;
77 cl::symbols<value::tag_type> doc_attributes;
78 std::map<value::tag_type, cl::rule<scanner>*> attribute_rules;
79 value::tag_type attribute_tag;
80 cl::rule<scanner> attribute_rule;
81 assign_attribute_type assign_attribute;
82 fallback_attribute_type fallback_attribute;
83
84 doc_info_grammar_local()
85 : assign_attribute(*this), fallback_attribute(*this)
86 {
87 }
88
89 bool source_mode_unset;
90 };
91
92 void quickbook_grammar::impl::init_doc_info()
93 {
94 doc_info_grammar_local& local =
95 cleanup_.add(new doc_info_grammar_local);
96
97 typedef cl::uint_parser<int, 10, 1, 2> uint2_t;
98
99 local.doc_types = "book", "article", "library", "chapter", "part",
100 "appendix", "preface", "qandadiv", "qandaset", "reference", "set";
101
102 BOOST_FOREACH (value::tag_type t, doc_attributes::tags()) {
103 local.doc_attributes.add(doc_attributes::name(t), t);
104 local.doc_info_attributes.add(doc_attributes::name(t), t);
105 }
106
107 BOOST_FOREACH (value::tag_type t, doc_info_attributes::tags()) {
108 local.doc_info_attributes.add(doc_info_attributes::name(t), t);
109 }
110
111 // Actions
112 error_action error(state);
113 plain_char_action plain_char(state);
114 do_macro_action do_macro(state);
115 scoped_parser<to_value_scoped_action> to_value(state);
116 member_action_value<quickbook::state, source_mode_type>
117 change_source_mode(state, &state::change_source_mode);
118 member_action_fixed_value<quickbook::state, source_mode_type>
119 default_source_mode(
120 state, &state::change_source_mode, source_mode_tags::cpp);
121
122 // clang-format off
123
124 doc_info_details =
125 cl::eps_p [ph::var(local.source_mode_unset) = true]
126 >> *( space
127 >> local.doc_attribute
128 )
129 >> !( space
130 >> local.doc_info_block
131 )
132 >> *eol
133 ;
134
135 local.doc_info_block =
136 '['
137 >> space
138 >> (local.doc_types >> cl::eps_p)
139 [state.values.entry(ph::arg1, ph::arg2, doc_info_tags::type)]
140 >> hard_space
141 >> to_value(doc_info_tags::title)
142 [ *( ~cl::eps_p(blank >> (cl::ch_p('[') | ']' | cl::eol_p))
143 >> local.char_
144 )
145 // Include 'blank' here so that it will be included in
146 // id generation.
147 >> blank
148 ]
149 >> space
150 >> !(qbk_ver(106u) >> cl::eps_p(ph::var(local.source_mode_unset))
151 [default_source_mode]
152 )
153 >> ( *( ( local.doc_info_attribute
154 | local.doc_info_escaped_attributes
155 )
156 >> space
157 )
158 ) [state.values.sort()]
159 >> ( ']'
160 >> (eol | cl::end_p)
161 | cl::eps_p [error]
162 )
163 ;
164
165 local.doc_attribute =
166 '['
167 >> space
168 >> local.doc_attributes [local.assign_attribute]
169 >> hard_space
170 >> state.values.list(ph::var(local.attribute_tag))
171 [ cl::eps_p [state.values.entry(ph::arg1, ph::arg2, doc_info_tags::before_docinfo)]
172 >> local.attribute_rule
173 ]
174 >> space
175 >> ']'
176 ;
177
178 local.doc_info_attribute =
179 '['
180 >> space
181 >> ( local.doc_info_attributes
182 [local.assign_attribute]
183 | (+(cl::alnum_p | '_' | '-'))
184 [local.fallback_attribute]
185 [error("Unrecognized document attribute: '%s'.")]
186 )
187 >> hard_space
188 >> state.values.list(ph::var(local.attribute_tag))
189 [local.attribute_rule]
190 >> space
191 >> ']'
192 ;
193
194 local.doc_fallback = to_value() [
195 *(~cl::eps_p(']') >> local.char_)
196 ];
197
198 local.doc_info_escaped_attributes =
199 ("'''" >> !eol)
200 >> (*(cl::anychar_p - "'''")) [state.values.entry(ph::arg1, ph::arg2, doc_info_tags::escaped_attribute)]
201 >> ( cl::str_p("'''")
202 | cl::eps_p [error("Unclosed boostbook escape.")]
203 )
204 ;
205
206 // Document Attributes
207
208 local.quickbook_version =
209 cl::uint_p [state.values.entry(ph::arg1)]
210 >> '.'
211 >> uint2_t() [state.values.entry(ph::arg1)]
212 ;
213
214 local.attribute_rules[doc_attributes::qbk_version] = &local.quickbook_version;
215
216 local.doc_compatibility_mode =
217 cl::uint_p [state.values.entry(ph::arg1)]
218 >> '.'
219 >> uint2_t() [state.values.entry(ph::arg1)]
220 ;
221
222 local.attribute_rules[doc_attributes::compatibility_mode] = &local.doc_compatibility_mode;
223
224 local.doc_source_mode = source_modes
225 [change_source_mode]
226 [ph::var(local.source_mode_unset) = false]
227 ;
228
229 local.attribute_rules[doc_attributes::source_mode] = &local.doc_source_mode;
230
231 // Document Info Attributes
232
233 local.doc_simple = to_value() [*(~cl::eps_p(']') >> local.char_)];
234 local.attribute_rules[doc_info_attributes::version] = &local.doc_simple;
235 local.attribute_rules[doc_info_attributes::id] = &local.doc_simple;
236 local.attribute_rules[doc_info_attributes::dirname] = &local.doc_simple;
237 local.attribute_rules[doc_info_attributes::category] = &local.doc_simple;
238 local.attribute_rules[doc_info_attributes::last_revision] = &local.doc_simple;
239 local.attribute_rules[doc_info_attributes::lang] = &local.doc_simple;
240 local.attribute_rules[doc_info_attributes::xmlbase] = &local.doc_simple;
241
242 local.doc_copyright_holder
243 = *( ~cl::eps_p
244 ( ']'
245 | ',' >> space >> local.doc_copyright_year
246 )
247 >> local.char_
248 );
249
250 local.doc_copyright =
251 *( +( local.doc_copyright_year
252 [state.values.entry(ph::arg1, doc_info_tags::copyright_year)]
253 >> space
254 >> !( '-'
255 >> space
256 >> local.doc_copyright_year
257 [state.values.entry(ph::arg1, doc_info_tags::copyright_year_end)]
258 >> space
259 )
260 >> !cl::ch_p(',')
261 >> space
262 )
263 >> to_value(doc_info_tags::copyright_name) [ local.doc_copyright_holder ]
264 >> !cl::ch_p(',')
265 >> space
266 )
267 ;
268
269 local.attribute_rules[doc_info_attributes::copyright] = &local.doc_copyright;
270
271 local.doc_phrase = to_value() [ nested_phrase ];
272 local.attribute_rules[doc_info_attributes::purpose] = &local.doc_phrase;
273 local.attribute_rules[doc_info_attributes::license] = &local.doc_phrase;
274
275 local.doc_author =
276 '['
277 >> space
278 >> to_value(doc_info_tags::author_surname)
279 [*(~cl::eps_p(',') >> local.char_)]
280 >> ',' >> space
281 >> to_value(doc_info_tags::author_first)
282 [*(~cl::eps_p(']') >> local.char_)]
283 >> ']'
284 ;
285
286 local.doc_authors =
287 *( local.doc_author
288 >> space
289 >> !(cl::ch_p(',') >> space)
290 )
291 ;
292
293 local.attribute_rules[doc_info_attributes::authors] = &local.doc_authors;
294
295 local.doc_biblioid =
296 (+cl::alnum_p) [state.values.entry(ph::arg1, ph::arg2, doc_info_tags::biblioid_class)]
297 >> hard_space
298 >> to_value(doc_info_tags::biblioid_value)
299 [+(~cl::eps_p(']') >> local.char_)]
300 ;
301
302 local.attribute_rules[doc_info_attributes::biblioid] = &local.doc_biblioid;
303
304 local.char_ =
305 escape
306 | local.macro
307 | cl::anychar_p[plain_char];
308 ;
309
310 local.macro =
311 cl::eps_p
312 ( ( state.macro
313 >> ~cl::eps_p(cl::alpha_p | '_')
314 // must not be followed by alpha or underscore
315 )
316 & macro_identifier // must be a valid macro for the current version
317 )
318 >> state.macro [do_macro]
319 ;
320
321 // clang-format on
322 }
323 }