summaryrefslogtreecommitdiffstats
path: root/src/boost/tools/quickbook/src/parsers.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/tools/quickbook/src/parsers.hpp')
-rw-r--r--src/boost/tools/quickbook/src/parsers.hpp305
1 files changed, 305 insertions, 0 deletions
diff --git a/src/boost/tools/quickbook/src/parsers.hpp b/src/boost/tools/quickbook/src/parsers.hpp
new file mode 100644
index 000000000..ac15d6471
--- /dev/null
+++ b/src/boost/tools/quickbook/src/parsers.hpp
@@ -0,0 +1,305 @@
+/*=============================================================================
+ Copyright (c) 2010-2011 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)
+ =============================================================================*/
+
+// Some custom parsers for use in quickbook.
+
+#ifndef BOOST_QUICKBOOK_PARSERS_HPP
+#define BOOST_QUICKBOOK_PARSERS_HPP
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_nil.hpp>
+#include <boost/spirit/include/phoenix1_binders.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_tuples.hpp>
+#include "fwd.hpp"
+#include "iterator.hpp"
+
+namespace quickbook
+{
+ namespace cl = boost::spirit::classic;
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // scoped_parser<Impl>
+ //
+ // Impl is a struct with the methods:
+ //
+ // void start();
+ // void success(parse_iterator, parse_iterator);
+ // void failure();
+ // void cleanup();
+ //
+ ///////////////////////////////////////////////////////////////////////////
+
+ template <typename Impl, typename Arguments, typename ParserT>
+ struct scoped_parser_impl
+ : public cl::unary<
+ ParserT,
+ cl::parser<scoped_parser_impl<Impl, Arguments, ParserT> > >
+ {
+ typedef scoped_parser_impl<Impl, Arguments, ParserT> self_t;
+ typedef cl::unary<
+ ParserT,
+ cl::parser<scoped_parser_impl<Impl, Arguments, ParserT> > >
+ base_t;
+
+ template <typename ScannerT> struct result
+ {
+ typedef cl::match<> type;
+ };
+
+ scoped_parser_impl(
+ Impl const& impl, Arguments const& arguments, ParserT const& p)
+ : base_t(p), impl_(impl), arguments_(arguments)
+ {
+ }
+
+ struct scoped
+ {
+ explicit scoped(Impl const& impl) : impl_(impl), in_progress_(false)
+ {
+ }
+
+ typedef phoenix::tuple_index<0> t0;
+ typedef phoenix::tuple_index<1> t1;
+
+ bool start(phoenix::tuple<> const&)
+ {
+ in_progress_ = impl_.start();
+ return in_progress_;
+ }
+
+ template <typename Arg1> bool start(phoenix::tuple<Arg1> const& x)
+ {
+ in_progress_ =
+ phoenix::bind(&Impl::start)(phoenix::var(impl_), x[t0()])();
+ return in_progress_;
+ }
+
+ template <typename Arg1, typename Arg2>
+ bool start(phoenix::tuple<Arg1, Arg2> const& x)
+ {
+ in_progress_ = phoenix::bind(&Impl::start)(
+ phoenix::var(impl_), x[t0()], x[t1()])();
+ return in_progress_;
+ }
+
+ void success(parse_iterator f, parse_iterator l)
+ {
+ in_progress_ = false;
+ impl_.success(f, l);
+ }
+
+ void failure()
+ {
+ in_progress_ = false;
+ impl_.failure();
+ }
+
+ ~scoped()
+ {
+ if (in_progress_) impl_.failure();
+ impl_.cleanup();
+ }
+
+ Impl impl_;
+ bool in_progress_;
+ };
+
+ template <typename ScannerT>
+ typename result<ScannerT>::type parse(ScannerT const& scan) const
+ {
+ typedef typename ScannerT::iterator_t iterator_t;
+ iterator_t save = scan.first;
+
+ scoped scope(impl_);
+ if (!scope.start(arguments_)) return scan.no_match();
+
+ typename cl::parser_result<ParserT, ScannerT>::type r =
+ this->subject().parse(scan);
+
+ bool success = scope.impl_.result(r, scan);
+
+ if (success) {
+ scope.success(save, scan.first);
+
+ if (r) {
+ return scan.create_match(
+ r.length(), cl::nil_t(), save, scan.first);
+ }
+ else {
+ return scan.create_match(
+ scan.first.base() - save.base(), cl::nil_t(), save,
+ scan.first);
+ }
+ }
+ else {
+ scope.failure();
+ return scan.no_match();
+ }
+ }
+
+ Impl impl_;
+ Arguments arguments_;
+ };
+
+ template <typename Impl, typename Arguments> struct scoped_parser_gen
+ {
+ explicit scoped_parser_gen(Impl impl, Arguments const& arguments)
+ : impl_(impl), arguments_(arguments)
+ {
+ }
+
+ template <typename ParserT>
+ scoped_parser_impl<
+ Impl,
+ Arguments,
+ 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<Impl, Arguments, parser_t>(
+ impl_, arguments_, p);
+ }
+
+ Impl impl_;
+ Arguments arguments_;
+ };
+
+ template <typename Impl> struct scoped_parser
+ {
+ scoped_parser(Impl const& impl) : impl_(impl) {}
+
+ scoped_parser_gen<Impl, phoenix::tuple<> > operator()() const
+ {
+ typedef phoenix::tuple<> tuple;
+ return scoped_parser_gen<Impl, tuple>(impl_, tuple());
+ }
+
+ template <typename Arg1>
+ scoped_parser_gen<Impl, phoenix::tuple<Arg1> > operator()(Arg1 x1) const
+ {
+ typedef phoenix::tuple<Arg1> tuple;
+ return scoped_parser_gen<Impl, tuple>(impl_, tuple(x1));
+ }
+
+ template <typename Arg1, typename Arg2>
+ scoped_parser_gen<Impl, phoenix::tuple<Arg1, Arg2> > operator()(
+ Arg1 x1, Arg2 x2) const
+ {
+ typedef phoenix::tuple<Arg1, Arg2> tuple;
+ return scoped_parser_gen<Impl, tuple>(impl_, tuple(x1, x2));
+ }
+
+ Impl impl_;
+
+ private:
+ scoped_parser& operator=(scoped_parser const&);
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // Lookback parser
+ //
+ // usage: lookback[body]
+ //
+ // Requires that iterator has typedef 'lookback_range' and function
+ // 'lookback' returning a 'lookback_range'.
+ //
+ ///////////////////////////////////////////////////////////////////////////
+
+ template <typename ParserT>
+ struct lookback_parser
+ : public cl::unary<ParserT, cl::parser<lookback_parser<ParserT> > >
+ {
+ typedef lookback_parser<ParserT> self_t;
+ typedef cl::unary<ParserT, cl::parser<lookback_parser<ParserT> > >
+ base_t;
+
+ template <typename ScannerT> struct result
+ {
+ typedef typename cl::parser_result<ParserT, ScannerT>::type type;
+ };
+
+ lookback_parser(ParserT const& p) : base_t(p) {}
+
+ template <typename ScannerT>
+ typename result<ScannerT>::type parse(ScannerT const& scan) const
+ {
+ typedef typename ScannerT::iterator_t::lookback_range::iterator
+ iterator_t;
+ typedef cl::scanner<iterator_t, typename ScannerT::policies_t>
+ scanner_t;
+
+ iterator_t begin = scan.first.lookback().begin();
+ scanner_t lookback_scan(begin, scan.first.lookback().end(), scan);
+
+ if (this->subject().parse(lookback_scan))
+ return scan.empty_match();
+ else
+ return scan.no_match();
+ }
+ };
+
+ struct lookback_gen
+ {
+ template <typename ParserT>
+ lookback_parser<ParserT> operator[](ParserT const& p) const
+ {
+ return lookback_parser<ParserT>(p);
+ }
+ };
+
+ lookback_gen const lookback = lookback_gen();
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // UTF-8 code point
+ //
+ // Very crude, it doesn't check that the code point is in any way valid.
+ // Just looks for the beginning of the next character. This is just for
+ // implementing some crude fixes, rather than full unicode support. I'm
+ // sure experts would be appalled.
+ //
+ ///////////////////////////////////////////////////////////////////////////
+
+ struct u8_codepoint_parser : public cl::parser<u8_codepoint_parser>
+ {
+ typedef u8_codepoint_parser self_t;
+
+ template <typename Scanner> struct result
+ {
+ typedef cl::match<> type;
+ };
+
+ template <typename Scanner>
+ typename result<Scanner>::type parse(Scanner const& scan) const
+ {
+ typedef typename Scanner::iterator_t iterator_t;
+
+ if (scan.at_end()) return scan.no_match();
+
+ iterator_t save(scan.first);
+
+ do {
+ ++scan.first;
+ } while (!scan.at_end() &&
+ ((unsigned char)*scan.first & 0xc0) == 0x80);
+
+ return scan.create_match(
+ scan.first.base() - save.base(), cl::nil_t(), save, scan.first);
+ }
+ };
+
+ u8_codepoint_parser const u8_codepoint_p = u8_codepoint_parser();
+}
+
+#endif // BOOST_QUICKBOOK_SCOPED_BLOCK_HPP