Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67632 - in trunk/tools/quickbook: src test
From: dnljms_at_[hidden]
Date: 2011-01-03 17:09:14


Author: danieljames
Date: 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
New Revision: 67632
URL: http://svn.boost.org/trac/boost/changeset/67632

Log:
Make the scoped parser more generic and use it for conditional phrases.
Added:
   trunk/tools/quickbook/src/scoped_parser.hpp (contents, props changed)
Removed:
   trunk/tools/quickbook/src/scoped_block.hpp
Text files modified:
   trunk/tools/quickbook/src/actions.cpp | 64 +++++++++++++++++++---------
   trunk/tools/quickbook/src/actions.hpp | 87 +++++++++++++++++++++++++++------------
   trunk/tools/quickbook/src/actions_class.cpp | 5 +
   trunk/tools/quickbook/src/actions_class.hpp | 9 +++
   trunk/tools/quickbook/src/block_markup_grammar.cpp | 19 ++++----
   trunk/tools/quickbook/src/main_grammar.cpp | 1
   trunk/tools/quickbook/src/phrase_markup_grammar.cpp | 2
   trunk/tools/quickbook/test/anchor.gold | 9 ++-
   trunk/tools/quickbook/test/anchor.quickbook | 10 +++-
   9 files changed, 135 insertions(+), 71 deletions(-)

Modified: trunk/tools/quickbook/src/actions.cpp
==============================================================================
--- trunk/tools/quickbook/src/actions.cpp (original)
+++ trunk/tools/quickbook/src/actions.cpp 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
@@ -199,32 +199,35 @@
 
     void cond_phrase_action_pre::operator()(iterator first, iterator last) const
     {
- // TODO: It would probably be better to save the anchors and restore
- // them if the phrase isn't used.
- actions.output_pre(out);
-
         std::string str(first, last);
- conditions.push_back(find(macro, str.c_str()));
- out.push(); // save the stream
+ condition = find(macro, str.c_str());
     }
 
- void cond_phrase_action_post::operator()(iterator first, iterator last) const
+ cond_phrase_push::cond_phrase_push(quickbook::actions& actions)
+ : actions(actions)
+ , condition(actions.condition)
+ , saved_anchors(actions.anchors)
+ , popped(false)
     {
- bool symbol_found = conditions.back();
- conditions.pop_back();
-
- if (first == last || !symbol_found)
- {
- // clear any anchors defined in the conditional phrase.
- actions.anchors.clear();
- out.pop(); // restore the stream
+ actions.phrase.push();
+ }
+
+ cond_phrase_push::~cond_phrase_push()
+ {
+ if(!popped) {
+ actions.phrase.pop();
+ actions.anchors.swap(saved_anchors);
         }
- else
- {
- std::string save;
- out.swap(save);
- out.pop(); // restore the stream
- out << save; // print the body
+ }
+
+ void cond_phrase_push::success_impl()
+ {
+ if(condition) {
+ std::string tmp;
+ actions.phrase.swap(tmp);
+ actions.phrase.pop();
+ actions.phrase.swap(tmp);
+ popped = true;
         }
     }
 
@@ -1474,4 +1477,23 @@
     {
         (*this)(actions.out);
     }
+
+ scoped_block_push::scoped_block_push(quickbook::actions& actions)
+ : actions(actions)
+ {
+ actions.out.push();
+ actions.phrase.push();
+ }
+
+ scoped_block_push::~scoped_block_push()
+ {
+ actions.phrase.pop();
+ actions.out.pop();
+ }
+
+ std::string const& scoped_block_push::success_impl()
+ {
+ actions.inside_paragraph();
+ return actions.out.str();
+ }
 }

Modified: trunk/tools/quickbook/src/actions.hpp
==============================================================================
--- trunk/tools/quickbook/src/actions.hpp (original)
+++ trunk/tools/quickbook/src/actions.hpp 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
@@ -73,6 +73,44 @@
         actions& escape_actions,
         std::string const& source_mode);
 
+ template <typename Derived, typename DataT = void>
+ struct scoped_action_base
+ {
+ typedef quickbook::actions data_type;
+
+ template <typename T>
+ struct result
+ {
+ typedef cl::match<DataT> type;
+ };
+
+ template <typename T>
+ DataT success(T const&)
+ {
+ return static_cast<Derived*>(this)->success_impl();
+ }
+
+ void failure() {
+ return static_cast<Derived*>(this)->failure_impl();
+ }
+
+ void failure_impl() {}
+ };
+
+ struct void_type {};
+
+ template <typename Derived>
+ struct scoped_action_base<Derived, void>
+ : scoped_action_base<Derived, void_type>
+ {
+ template <typename T>
+ void_type success(T const&)
+ {
+ static_cast<Derived*>(this)->success_impl();
+ return void_type();
+ }
+ };
+
     struct error_action
     {
         // Prints an error message to std::cerr
@@ -260,43 +298,27 @@
         // Handles conditional phrases
 
         cond_phrase_action_pre(
- collector& out
- , std::vector<bool>& conditions
- , string_symbols const& macro
- , quickbook::actions& actions)
- : out(out)
- , conditions(conditions)
- , macro(macro)
- , actions(actions) {}
+ bool& condition
+ , string_symbols const& macro)
+ : condition(condition)
+ , macro(macro) {}
 
         void operator()(iterator first, iterator last) const;
 
- collector& out;
- std::vector<bool>& conditions;
+ bool& condition;
         string_symbols const& macro;
- quickbook::actions& actions;
     };
 
- struct cond_phrase_action_post
+ struct cond_phrase_push : scoped_action_base<cond_phrase_push>
     {
- // Handles conditional phrases
-
- cond_phrase_action_post(
- collector& out
- , std::vector<bool>& conditions
- , string_symbols const& macro
- , quickbook::actions& actions)
- : out(out)
- , conditions(conditions)
- , macro(macro)
- , actions(actions) {}
-
- void operator()(iterator first, iterator last) const;
+ cond_phrase_push(quickbook::actions&);
+ ~cond_phrase_push();
+ void success_impl();
 
- collector& out;
- std::vector<bool>& conditions;
- string_symbols const& macro;
         quickbook::actions& actions;
+ bool condition;
+ std::vector<std::string> saved_anchors;
+ bool popped;
     };
 
     struct list_action
@@ -916,6 +938,15 @@
         
         quickbook::actions& actions;
     };
+
+ struct scoped_block_push : scoped_action_base<scoped_block_push, std::string>
+ {
+ scoped_block_push(quickbook::actions&);
+ ~scoped_block_push();
+ std::string const& success_impl();
+
+ quickbook::actions& actions;
+ };
 }
 
 #ifdef BOOST_MSVC

Modified: trunk/tools/quickbook/src/actions_class.cpp
==============================================================================
--- trunk/tools/quickbook/src/actions_class.cpp (original)
+++ trunk/tools/quickbook/src/actions_class.cpp 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
@@ -84,6 +84,7 @@
         , extract_doc_category(doc_category, phrase, *this)
         , extract_doc_biblioid(doc_biblioid.second, phrase, *this)
         , extract_doc_lang(doc_lang, phrase, *this)
+ , scoped_block(*this)
         , code(out, phrase, *this)
         , code_block(phrase, phrase, *this)
         , inline_code(phrase, *this)
@@ -110,8 +111,8 @@
         , escape_unicode(phrase, *this)
         , attribute(attributes, attribute_name, error_count)
         , image(phrase, attributes, image_fileref, *this)
- , cond_phrase_pre(phrase, conditions, macro, *this)
- , cond_phrase_post(phrase, conditions, macro, *this)
+ , cond_phrase_pre(condition, macro)
+ , scoped_cond_phrase(*this)
 
         , list(out, list_buffer, list_indent, list_marks, *this)
         , list_format(list_buffer, list_indent, list_marks, error_count, *this)

Modified: trunk/tools/quickbook/src/actions_class.hpp
==============================================================================
--- trunk/tools/quickbook/src/actions_class.hpp (original)
+++ trunk/tools/quickbook/src/actions_class.hpp 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
@@ -11,6 +11,7 @@
 #define BOOST_SPIRIT_ACTIONS_CLASS_HPP
 
 #include "actions.hpp"
+#include "scoped_parser.hpp"
 #include <boost/tuple/tuple.hpp>
 
 namespace quickbook
@@ -102,7 +103,7 @@
         std::string macro_id;
         std::stack<mark_type> list_marks;
         int list_indent;
- std::vector<bool> conditions;
+ bool condition;
         std::string template_identifier;
         string_list template_info;
         int template_depth;
@@ -141,6 +142,9 @@
         phrase_to_docinfo_action extract_doc_biblioid;
         phrase_to_docinfo_action extract_doc_lang;
 
+ scoped_parser<scoped_block_push>
+ scoped_block;
+
         code_action code;
         code_action code_block;
         inline_code_action inline_code;
@@ -158,7 +162,8 @@
         attribute_action attribute;
         image_action image;
         cond_phrase_action_pre cond_phrase_pre;
- cond_phrase_action_post cond_phrase_post;
+ scoped_parser<cond_phrase_push>
+ scoped_cond_phrase;
 
         list_action list;
         list_format_action list_format;

Modified: trunk/tools/quickbook/src/block_markup_grammar.cpp
==============================================================================
--- trunk/tools/quickbook/src/block_markup_grammar.cpp (original)
+++ trunk/tools/quickbook/src/block_markup_grammar.cpp 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
@@ -8,7 +8,6 @@
     http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 
-#include "scoped_block.hpp"
 #include "utils.hpp"
 #include "actions_class.hpp"
 #include "grammar_impl.hpp"
@@ -111,7 +110,7 @@
         block_keyword_rules.add("blurb", &local.blurb);
 
         local.blurb =
- scoped_block(actions)[inside_paragraph]
+ actions.scoped_block[inside_paragraph]
                                                 [actions.blurb]
             ;
 
@@ -120,7 +119,7 @@
             ;
 
         local.blockquote =
- blank >> scoped_block(actions)[inside_paragraph]
+ blank >> actions.scoped_block[inside_paragraph]
                                                 [actions.blockquote]
             ;
 
@@ -133,27 +132,27 @@
             ;
 
         local.warning =
- scoped_block(actions)[inside_paragraph]
+ actions.scoped_block[inside_paragraph]
                                                 [actions.warning]
             ;
 
         local.caution =
- scoped_block(actions)[inside_paragraph]
+ actions.scoped_block[inside_paragraph]
                                                 [actions.caution]
             ;
 
         local.important =
- scoped_block(actions)[inside_paragraph]
+ actions.scoped_block[inside_paragraph]
                                                 [actions.important]
             ;
 
         local.note =
- scoped_block(actions)[inside_paragraph]
+ actions.scoped_block[inside_paragraph]
                                                 [actions.note]
             ;
 
         local.tip =
- scoped_block(actions)[inside_paragraph]
+ actions.scoped_block[inside_paragraph]
                                                 [actions.tip]
             ;
 
@@ -234,7 +233,7 @@
             (
                 (
                     local.varlistterm
- >> ( scoped_block(actions) [+local.varlistitem]
+ >> ( actions.scoped_block [+local.varlistitem]
                                                 [actions.varlistitem]
                         | cl::eps_p [actions.error]
                         )
@@ -304,7 +303,7 @@
         local.table_cell =
                 space
>> cl::ch_p('[')
- >> ( scoped_block(actions) [
+ >> ( actions.scoped_block [
                         inside_paragraph
>> cl::ch_p(']')
>> space

Modified: trunk/tools/quickbook/src/main_grammar.cpp
==============================================================================
--- trunk/tools/quickbook/src/main_grammar.cpp (original)
+++ trunk/tools/quickbook/src/main_grammar.cpp 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
@@ -11,7 +11,6 @@
 #include "grammar_impl.hpp"
 #include "actions_class.hpp"
 #include "utils.hpp"
-#include "scoped_block.hpp"
 #include <boost/spirit/include/classic_core.hpp>
 #include <boost/spirit/include/classic_confix.hpp>
 #include <boost/spirit/include/classic_chset.hpp>

Modified: trunk/tools/quickbook/src/phrase_markup_grammar.cpp
==============================================================================
--- trunk/tools/quickbook/src/phrase_markup_grammar.cpp (original)
+++ trunk/tools/quickbook/src/phrase_markup_grammar.cpp 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
@@ -47,7 +47,7 @@
         local.cond_phrase =
                 blank
>> macro_identifier [actions.cond_phrase_pre]
- >> (!phrase) [actions.cond_phrase_post]
+ >> actions.scoped_cond_phrase[phrase]
             ;
 
         phrase_symbol_rules.add

Deleted: trunk/tools/quickbook/src/scoped_block.hpp
==============================================================================
--- trunk/tools/quickbook/src/scoped_block.hpp 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
+++ (empty file)
@@ -1,133 +0,0 @@
-/*=============================================================================
- Copyright (c) 2010 Daniel James
- Copyright (c) 2003 Martin Wille
- http://spirit.sourceforge.net/
-
- Distributed under 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)
- =============================================================================*/
-
-// Used to parse an inner block, saves the streams and restores them if the
-// parse fails. On success the action is passed the resulting block.
-//
-// Might be a good idea to do something more generic in the future.
-//
-// This is based on `boost::spirit::classic::scoped_lock` by Martin Wille
-
-#ifndef BOOST_QUICKBOOK_SCOPED_BLOCK_HPP
-#define BOOST_QUICKBOOK_SCOPED_BLOCK_HPP
-
-#include <boost/spirit/include/classic_core.hpp>
-#include "actions_class.hpp"
-
-namespace quickbook {
-
- namespace cl = boost::spirit::classic;
-
- struct scoped_block_push
- {
- typedef std::string attribute;
-
- scoped_block_push(quickbook::actions& actions)
- : actions(actions)
- {
- actions.out.push();
- actions.phrase.push();
- }
-
- ~scoped_block_push()
- {
- actions.phrase.pop();
- actions.out.pop();
- }
-
- std::string const& finish()
- {
- actions.inside_paragraph();
- return actions.out.str();
- }
-
- quickbook::actions& actions;
- };
-
- template <typename ParserT>
- struct scoped_block_parser
- : public cl::unary< ParserT, cl::parser< scoped_block_parser<ParserT> > >
- {
- typedef scoped_block_parser<ParserT> self_t;
- typedef cl::unary< ParserT, cl::parser< scoped_block_parser<ParserT> > > base_t;
-
- template <typename ScannerT>
- struct result
- {
- typedef cl::match<std::string> type;
- };
-
- scoped_block_parser(quickbook::actions& a, ParserT const &p)
- : base_t(p)
- , actions(a)
- {}
-
- template <typename ScannerT>
- cl::match<std::string> parse(ScannerT const &scan) const
- {
- typedef typename ScannerT::iterator_t iterator_t;
- iterator_t save = scan.first;
-
- scoped_block_push push(actions);
- typename cl::parser_result<ParserT, ScannerT>::type result
- = this->subject().parse(scan);
-
- if (result)
- return scan.create_match(result.length(), push.finish(), save, scan.first);
- else
- return scan.no_match();
- }
-
- quickbook::actions& actions;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // scoped_block_parser_gen
- //
- // generator for scoped_block_parser objects
- // operator[] returns scoped_block_parser according to its argument
- //
- ///////////////////////////////////////////////////////////////////////////
- struct scoped_block_parser_gen
- {
- explicit scoped_block_parser_gen(quickbook::actions& actions)
- : actions(actions) {}
-
- template<typename ParserT>
- scoped_block_parser
- <
- typename cl::as_parser<ParserT>::type
- >
- operator[](ParserT const &p) const
- {
- typedef cl::as_parser<ParserT> as_parser_t;
- typedef typename as_parser_t::type parser_t;
-
- return scoped_block_parser<parser_t>
- (actions, as_parser_t::convert(p));
- }
-
- quickbook::actions& actions;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- //
- // scoped_block_d parser directive
- //
- // constructs a scoped_block_parser generator from its argument
- //
- ///////////////////////////////////////////////////////////////////////////
- inline scoped_block_parser_gen scoped_block(quickbook::actions& actions) {
- return scoped_block_parser_gen(actions);
- }
-
-}
-#endif // BOOST_QUICKBOOK_SCOPED_BLOCK_HPP

Added: trunk/tools/quickbook/src/scoped_parser.hpp
==============================================================================
--- (empty file)
+++ trunk/tools/quickbook/src/scoped_parser.hpp 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
@@ -0,0 +1,97 @@
+/*=============================================================================
+ Copyright (c) 2010 Daniel James
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Distributed under 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)
+ =============================================================================*/
+
+// Used to store variables/state while parsing
+
+#ifndef BOOST_QUICKBOOK_SCOPED_PARSER_HPP
+#define BOOST_QUICKBOOK_SCOPED_PARSER_HPP
+
+#include <boost/spirit/include/classic_core.hpp>
+
+namespace quickbook {
+ namespace cl = boost::spirit::classic;
+
+ template <typename ScopeT, typename DataT, typename ParserT>
+ struct scoped_parser_impl
+ : public cl::unary< ParserT, cl::parser< scoped_parser_impl<ScopeT, DataT, ParserT> > >
+ {
+ typedef scoped_parser_impl<ScopeT, DataT, ParserT> self_t;
+ typedef cl::unary< ParserT, cl::parser< scoped_parser_impl<ScopeT, DataT, ParserT> > > base_t;
+
+ template <typename ScannerT>
+ struct result :
+ ScopeT::template result<
+ typename cl::parser_result<ParserT, ScannerT>::type
+ >
+ {
+ };
+
+ scoped_parser_impl(DataT& actions, ParserT const &p)
+ : base_t(p)
+ , actions(actions)
+ {}
+
+ template <typename ScannerT>
+ typename result<ScannerT>::type parse(ScannerT const &scan) const
+ {
+ typedef typename ScannerT::iterator_t iterator_t;
+ iterator_t save = scan.first;
+
+ ScopeT scope(actions);
+ typename cl::parser_result<ParserT, ScannerT>::type result
+ = this->subject().parse(scan);
+
+ if (result) {
+ return scan.create_match(result.length(), scope.success(result), save, scan.first);
+ }
+ else {
+ scope.failure();
+ return scan.no_match();
+ }
+ }
+
+ DataT& actions;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // scoped_parser
+ //
+ // generator for scoped_parser_impl objects
+ // operator[] returns scoped_parser_impl according to its argument
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename ScopeT>
+ struct scoped_parser
+ {
+ typedef typename ScopeT::data_type data_type;
+
+ explicit scoped_parser(data_type& actions)
+ : actions(actions) {}
+
+ template<typename ParserT>
+ scoped_parser_impl
+ <
+ ScopeT,
+ data_type,
+ typename cl::as_parser<ParserT>::type
+ >
+ operator[](ParserT const &p) const
+ {
+ typedef cl::as_parser<ParserT> as_parser_t;
+ typedef typename as_parser_t::type parser_t;
+
+ return scoped_parser_impl<ScopeT, data_type, parser_t>
+ (actions, as_parser_t::convert(p));
+ }
+
+ data_type& actions;
+ };
+}
+#endif // BOOST_QUICKBOOK_SCOPED_BLOCK_HPP

Modified: trunk/tools/quickbook/test/anchor.gold
==============================================================================
--- trunk/tools/quickbook/test/anchor.gold (original)
+++ trunk/tools/quickbook/test/anchor.gold 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
@@ -34,10 +34,13 @@
     <anchor id="a8"/>
   </section>
   <section id="anchor_test.section_anchor">
- <anchor id="a8"/> <title>Section Anchor</title>
+ <anchor id="a9"/> <title>Section Anchor</title>
     <section id="anchor_test.nested_section">
- <title>Nested Section</title>
+ <anchor id="a10"/> <title>Nested Section</title>
     </section>
- <anchor id="a9"/>
+ <anchor id="a11"/>
+ </section>
+ <section id="anchor_test.conditional_section_anchor">
+ <anchor id="a12"/> <title>Conditional Section Anchor</title>
   </section>
 </article>

Modified: trunk/tools/quickbook/test/anchor.quickbook
==============================================================================
--- trunk/tools/quickbook/test/anchor.quickbook (original)
+++ trunk/tools/quickbook/test/anchor.quickbook 2011-01-03 17:09:10 EST (Mon, 03 Jan 2011)
@@ -23,10 +23,14 @@
 
 [endsect]
 
-[#a8]
+[#a9]
 [section Section Anchor]
-[section Nested Section]
+[#a10][section Nested Section]
 [endsect]
 [/ This anchor is invalid, I'm not sure what to do with it]
-[#a9]
+[#a11]
 [endsect]
+
+[#a12][?__not_defined__ #a13]
+[section Conditional Section Anchor]
+[endsect]
\ No newline at end of file


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk