diff options
Diffstat (limited to '')
-rw-r--r-- | src/boost/tools/quickbook/src/doc_info_grammar.cpp | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/src/boost/tools/quickbook/src/doc_info_grammar.cpp b/src/boost/tools/quickbook/src/doc_info_grammar.cpp new file mode 100644 index 000000000..b3ca44aff --- /dev/null +++ b/src/boost/tools/quickbook/src/doc_info_grammar.cpp @@ -0,0 +1,323 @@ +/*============================================================================= + Copyright (c) 2002 2004 2006 Joel de Guzman + Copyright (c) 2004 Eric Niebler + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +#include <map> +#include <boost/spirit/include/classic_chset.hpp> +#include <boost/spirit/include/classic_core.hpp> +#include <boost/spirit/include/classic_loops.hpp> +#include <boost/spirit/include/classic_numerics.hpp> +#include <boost/spirit/include/classic_symbols.hpp> +#include <boost/spirit/include/phoenix1_operators.hpp> +#include <boost/spirit/include/phoenix1_primitives.hpp> +#include "actions.hpp" +#include "doc_info_tags.hpp" +#include "for.hpp" +#include "grammar_impl.hpp" +#include "phrase_tags.hpp" +#include "state.hpp" + +namespace quickbook +{ + namespace cl = boost::spirit::classic; + + struct attribute_info + { + attribute_info(value::tag_type t, cl::rule<scanner>* r) + : tag(t), rule(r) + { + } + + value::tag_type tag; + cl::rule<scanner>* rule; + }; + + struct doc_info_grammar_local + { + struct assign_attribute_type + { + assign_attribute_type(doc_info_grammar_local& l_) : l(l_) {} + + void operator()(value::tag_type& t) const + { + l.attribute_rule = *l.attribute_rules[t]; + l.attribute_tag = t; + } + + doc_info_grammar_local& l; + }; + + struct fallback_attribute_type + { + fallback_attribute_type(doc_info_grammar_local& l_) : l(l_) {} + + void operator()(parse_iterator, parse_iterator) const + { + l.attribute_rule = l.doc_fallback; + l.attribute_tag = value::default_tag; + } + + doc_info_grammar_local& l; + }; + + cl::rule<scanner> doc_info_block, doc_attribute, doc_info_attribute, + doc_info_escaped_attributes, doc_title, doc_simple, doc_phrase, + doc_fallback, doc_authors, doc_author, doc_copyright, + doc_copyright_holder, doc_source_mode, doc_biblioid, + doc_compatibility_mode, quickbook_version, macro, char_; + cl::uint_parser<int, 10, 4, 4> doc_copyright_year; + cl::symbols<> doc_types; + cl::symbols<value::tag_type> doc_info_attributes; + cl::symbols<value::tag_type> doc_attributes; + std::map<value::tag_type, cl::rule<scanner>*> attribute_rules; + value::tag_type attribute_tag; + cl::rule<scanner> attribute_rule; + assign_attribute_type assign_attribute; + fallback_attribute_type fallback_attribute; + + doc_info_grammar_local() + : assign_attribute(*this), fallback_attribute(*this) + { + } + + bool source_mode_unset; + }; + + void quickbook_grammar::impl::init_doc_info() + { + doc_info_grammar_local& local = + cleanup_.add(new doc_info_grammar_local); + + typedef cl::uint_parser<int, 10, 1, 2> uint2_t; + + local.doc_types = "book", "article", "library", "chapter", "part", + "appendix", "preface", "qandadiv", "qandaset", "reference", "set"; + + QUICKBOOK_FOR (value::tag_type t, doc_attributes::tags()) { + local.doc_attributes.add(doc_attributes::name(t), t); + local.doc_info_attributes.add(doc_attributes::name(t), t); + } + + QUICKBOOK_FOR (value::tag_type t, doc_info_attributes::tags()) { + local.doc_info_attributes.add(doc_info_attributes::name(t), t); + } + + // Actions + error_action error(state); + plain_char_action plain_char(state); + do_macro_action do_macro(state); + scoped_parser<to_value_scoped_action> to_value(state); + member_action_value<quickbook::state, source_mode_type> + change_source_mode(state, &state::change_source_mode); + member_action_fixed_value<quickbook::state, source_mode_type> + default_source_mode( + state, &state::change_source_mode, source_mode_tags::cpp); + + // clang-format off + + doc_info_details = + cl::eps_p [ph::var(local.source_mode_unset) = true] + >> *( space + >> local.doc_attribute + ) + >> !( space + >> local.doc_info_block + ) + >> *eol + ; + + local.doc_info_block = + '[' + >> space + >> (local.doc_types >> cl::eps_p) + [state.values.entry(ph::arg1, ph::arg2, doc_info_tags::type)] + >> hard_space + >> to_value(doc_info_tags::title) + [ *( ~cl::eps_p(blank >> (cl::ch_p('[') | ']' | cl::eol_p)) + >> local.char_ + ) + // Include 'blank' here so that it will be included in + // id generation. + >> blank + ] + >> space + >> !(qbk_ver(106u) >> cl::eps_p(ph::var(local.source_mode_unset)) + [default_source_mode] + ) + >> ( *( ( local.doc_info_attribute + | local.doc_info_escaped_attributes + ) + >> space + ) + ) [state.values.sort()] + >> ( ']' + >> (eol | cl::end_p) + | cl::eps_p [error] + ) + ; + + local.doc_attribute = + '[' + >> space + >> local.doc_attributes [local.assign_attribute] + >> hard_space + >> state.values.list(ph::var(local.attribute_tag)) + [ cl::eps_p [state.values.entry(ph::arg1, ph::arg2, doc_info_tags::before_docinfo)] + >> local.attribute_rule + ] + >> space + >> ']' + ; + + local.doc_info_attribute = + '[' + >> space + >> ( local.doc_info_attributes + [local.assign_attribute] + | (+(cl::alnum_p | '_' | '-')) + [local.fallback_attribute] + [error("Unrecognized document attribute: '%s'.")] + ) + >> hard_space + >> state.values.list(ph::var(local.attribute_tag)) + [local.attribute_rule] + >> space + >> ']' + ; + + local.doc_fallback = to_value() [ + *(~cl::eps_p(']') >> local.char_) + ]; + + local.doc_info_escaped_attributes = + ("'''" >> !eol) + >> (*(cl::anychar_p - "'''")) [state.values.entry(ph::arg1, ph::arg2, doc_info_tags::escaped_attribute)] + >> ( cl::str_p("'''") + | cl::eps_p [error("Unclosed boostbook escape.")] + ) + ; + + // Document Attributes + + local.quickbook_version = + cl::uint_p [state.values.entry(ph::arg1)] + >> '.' + >> uint2_t() [state.values.entry(ph::arg1)] + ; + + local.attribute_rules[doc_attributes::qbk_version] = &local.quickbook_version; + + local.doc_compatibility_mode = + cl::uint_p [state.values.entry(ph::arg1)] + >> '.' + >> uint2_t() [state.values.entry(ph::arg1)] + ; + + local.attribute_rules[doc_attributes::compatibility_mode] = &local.doc_compatibility_mode; + + local.doc_source_mode = source_modes + [change_source_mode] + [ph::var(local.source_mode_unset) = false] + ; + + local.attribute_rules[doc_attributes::source_mode] = &local.doc_source_mode; + + // Document Info Attributes + + local.doc_simple = to_value() [*(~cl::eps_p(']') >> local.char_)]; + local.attribute_rules[doc_info_attributes::version] = &local.doc_simple; + local.attribute_rules[doc_info_attributes::id] = &local.doc_simple; + local.attribute_rules[doc_info_attributes::dirname] = &local.doc_simple; + local.attribute_rules[doc_info_attributes::category] = &local.doc_simple; + local.attribute_rules[doc_info_attributes::last_revision] = &local.doc_simple; + local.attribute_rules[doc_info_attributes::lang] = &local.doc_simple; + local.attribute_rules[doc_info_attributes::xmlbase] = &local.doc_simple; + + local.doc_copyright_holder + = *( ~cl::eps_p + ( ']' + | ',' >> space >> local.doc_copyright_year + ) + >> local.char_ + ); + + local.doc_copyright = + *( +( local.doc_copyright_year + [state.values.entry(ph::arg1, doc_info_tags::copyright_year)] + >> space + >> !( '-' + >> space + >> local.doc_copyright_year + [state.values.entry(ph::arg1, doc_info_tags::copyright_year_end)] + >> space + ) + >> !cl::ch_p(',') + >> space + ) + >> to_value(doc_info_tags::copyright_name) [ local.doc_copyright_holder ] + >> !cl::ch_p(',') + >> space + ) + ; + + local.attribute_rules[doc_info_attributes::copyright] = &local.doc_copyright; + + local.doc_phrase = to_value() [ nested_phrase ]; + local.attribute_rules[doc_info_attributes::purpose] = &local.doc_phrase; + local.attribute_rules[doc_info_attributes::license] = &local.doc_phrase; + + local.doc_author = + '[' + >> space + >> to_value(doc_info_tags::author_surname) + [*(~cl::eps_p(',') >> local.char_)] + >> ',' >> space + >> to_value(doc_info_tags::author_first) + [*(~cl::eps_p(']') >> local.char_)] + >> ']' + ; + + local.doc_authors = + *( local.doc_author + >> space + >> !(cl::ch_p(',') >> space) + ) + ; + + local.attribute_rules[doc_info_attributes::authors] = &local.doc_authors; + + local.doc_biblioid = + (+cl::alnum_p) [state.values.entry(ph::arg1, ph::arg2, doc_info_tags::biblioid_class)] + >> hard_space + >> to_value(doc_info_tags::biblioid_value) + [+(~cl::eps_p(']') >> local.char_)] + ; + + local.attribute_rules[doc_info_attributes::biblioid] = &local.doc_biblioid; + + local.char_ = + escape + | local.macro + | cl::anychar_p[plain_char]; + ; + + local.macro = + cl::eps_p + ( ( state.macro + >> ~cl::eps_p(cl::alpha_p | '_') + // must not be followed by alpha or underscore + ) + & macro_identifier // must be a valid macro for the current version + ) + >> state.macro [do_macro] + ; + + // clang-format on + } +} |