summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/spirit/example/support
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/spirit/example/support
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/spirit/example/support')
-rw-r--r--src/boost/libs/spirit/example/support/Jamfile16
-rw-r--r--src/boost/libs/spirit/example/support/multi_pass.cpp50
-rw-r--r--src/boost/libs/spirit/example/support/multi_pass.txt6
-rw-r--r--src/boost/libs/spirit/example/support/utree/error_handler.hpp112
-rw-r--r--src/boost/libs/spirit/example/support/utree/parse_sexpr.cpp62
-rw-r--r--src/boost/libs/spirit/example/support/utree/sexpr_generator.hpp128
-rw-r--r--src/boost/libs/spirit/example/support/utree/sexpr_parser.hpp250
-rw-r--r--src/boost/libs/spirit/example/support/utree/utf8_parser.hpp138
8 files changed, 762 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/example/support/Jamfile b/src/boost/libs/spirit/example/support/Jamfile
new file mode 100644
index 00000000..273e341b
--- /dev/null
+++ b/src/boost/libs/spirit/example/support/Jamfile
@@ -0,0 +1,16 @@
+#==============================================================================
+# Copyright (c) 2001-2011 Joel de Guzman
+# Copyright (c) 2001-2011 Hartmut Kaiser
+# Copyright (C) 2011 Bryce Lelbach
+#
+# 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)
+#==============================================================================
+project spirit-support-example
+ : requirements <toolset>gcc:<c++-template-depth>300
+ :
+ :
+ ;
+
+exe multi_pass : multi_pass.cpp ;
+exe parse_sexpr : utree/parse_sexpr.cpp ;
diff --git a/src/boost/libs/spirit/example/support/multi_pass.cpp b/src/boost/libs/spirit/example/support/multi_pass.cpp
new file mode 100644
index 00000000..27e529c7
--- /dev/null
+++ b/src/boost/libs/spirit/example/support/multi_pass.cpp
@@ -0,0 +1,50 @@
+// Copyright (c) 2001-2010 Hartmut Kaiser
+//
+// 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)
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/support_multi_pass.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+//[tutorial_multi_pass
+int main()
+{
+ namespace spirit = boost::spirit;
+ using spirit::ascii::space;
+ using spirit::ascii::char_;
+ using spirit::qi::double_;
+ using spirit::qi::eol;
+
+ std::ifstream in("multi_pass.txt"); // we get our input from this file
+ if (!in.is_open()) {
+ std::cout << "Could not open input file: 'multi_pass.txt'" << std::endl;
+ return -1;
+ }
+
+ typedef std::istreambuf_iterator<char> base_iterator_type;
+ spirit::multi_pass<base_iterator_type> first =
+ spirit::make_default_multi_pass(base_iterator_type(in));
+
+ std::vector<double> v;
+ bool result = spirit::qi::phrase_parse(first
+ , spirit::make_default_multi_pass(base_iterator_type())
+ , double_ >> *(',' >> double_) // recognize list of doubles
+ , space | '#' >> *(char_ - eol) >> eol // comment skipper
+ , v); // data read from file
+
+ if (!result) {
+ std::cout << "Failed parsing input file!" << std::endl;
+ return -2;
+ }
+
+ std::cout << "Successfully parsed input file!" << std::endl;
+ return 0;
+}
+//]
diff --git a/src/boost/libs/spirit/example/support/multi_pass.txt b/src/boost/libs/spirit/example/support/multi_pass.txt
new file mode 100644
index 00000000..54368f38
--- /dev/null
+++ b/src/boost/libs/spirit/example/support/multi_pass.txt
@@ -0,0 +1,6 @@
+# Copyright (c) 2001-2009 Hartmut Kaiser
+#
+# 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)
+
+1.0,2.0,3.0
diff --git a/src/boost/libs/spirit/example/support/utree/error_handler.hpp b/src/boost/libs/spirit/example/support/utree/error_handler.hpp
new file mode 100644
index 00000000..6f5ba1bc
--- /dev/null
+++ b/src/boost/libs/spirit/example/support/utree/error_handler.hpp
@@ -0,0 +1,112 @@
+/*==============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2010-2011 Bryce Lelbach
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file BOOST_LICENSE_1_0.rst or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#if !defined(BOOST_SPIRIT_UTREE_EXAMPLE_ERROR_HANDLER_HPP)
+#define BOOST_SPIRIT_UTREE_EXAMPLE_ERROR_HANDLER_HPP
+
+#include <string>
+#include <sstream>
+
+#include <boost/config.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/include/support_line_pos_iterator.hpp>
+
+namespace sexpr
+{
+
+using boost::spirit::info;
+
+template <typename Out>
+struct print_info
+{
+ typedef boost::spirit::utf8_string string;
+
+ print_info(Out& out) : out(out), first(true) {}
+
+ void element(string const& tag, string const& value, int) const
+ {
+ if (!first) {
+ out << ' ';
+ first = false;
+ }
+
+ if (value == "")
+ out << tag;
+ else
+ out << "\"" << value << '"';
+ }
+
+ Out& out;
+ mutable bool first;
+};
+
+struct expected_component : std::exception
+{
+ std::string msg;
+
+ expected_component(std::string const& source, std::size_t line
+ , info const& w)
+ {
+ using boost::spirit::basic_info_walker;
+
+ std::ostringstream oss;
+ oss << "(exception \"" << source << "\" ";
+
+ if (line == -1)
+ oss << -1;
+ else
+ oss << line;
+
+ oss << " '(expected_component (";
+
+ print_info<std::ostringstream> pr(oss);
+ basic_info_walker<print_info<std::ostringstream> >
+ walker(pr, w.tag, 0);
+
+ boost::apply_visitor(walker, w.value);
+
+ oss << ")))";
+
+ msg = oss.str();
+ }
+
+ virtual ~expected_component() BOOST_NOEXCEPT_OR_NOTHROW {}
+
+ virtual char const* what() const BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ return msg.c_str();
+ }
+};
+
+template <typename Iterator>
+struct error_handler
+{
+ template <typename, typename, typename, typename>
+ struct result
+ {
+ typedef void type;
+ };
+
+ std::string source;
+
+ error_handler(std::string const& source_ = "<string>") : source(source_) {}
+
+ void operator()(Iterator first, Iterator last, Iterator err_pos
+ , info const& what) const
+ {
+ using boost::spirit::get_line;
+ Iterator eol = err_pos;
+ std::size_t line = get_line(err_pos);
+ throw expected_component(source, line, what);
+ }
+};
+
+} // sexpr
+
+#endif // BOOST_SPIRIT_UTREE_EXAMPLE_ERROR_HANDLER_HPP
+
diff --git a/src/boost/libs/spirit/example/support/utree/parse_sexpr.cpp b/src/boost/libs/spirit/example/support/utree/parse_sexpr.cpp
new file mode 100644
index 00000000..72d49ea5
--- /dev/null
+++ b/src/boost/libs/spirit/example/support/utree/parse_sexpr.cpp
@@ -0,0 +1,62 @@
+/*==============================================================================
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2010-2011 Bryce Lelbach
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file BOOST_LICENSE_1_0.rst or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#include <boost/spirit/include/support_istream_iterator.hpp>
+#include <boost/spirit/include/support_line_pos_iterator.hpp>
+#include <boost/spirit/include/qi_parse.hpp>
+
+#include "sexpr_parser.hpp"
+
+int
+main()
+{
+ using boost::spirit::qi::phrase_parse;
+
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "sexpr parser...\n\n";
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "Type an expression... or [q or Q] to quit\n\n";
+
+ typedef std::string::const_iterator iterator_type;
+ typedef sexpr::parser<iterator_type> parser;
+ typedef sexpr::whitespace<iterator_type> space;
+
+ parser p;
+ space ws;
+
+ std::string str;
+ while (std::getline(std::cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ std::string::const_iterator iter = str.begin();
+ std::string::const_iterator end = str.end();
+ bool r = phrase_parse(iter, end, p, ws);
+
+ if (r && iter == end)
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing succeeded\n";
+ std::cout << "-------------------------\n";
+ }
+ else
+ {
+ std::string rest(iter, end);
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing failed\n";
+ std::cout << "stopped at: \": " << rest << "\"\n";
+ std::cout << "-------------------------\n";
+ }
+ }
+
+ std::cout << "Bye... :-) \n\n";
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/example/support/utree/sexpr_generator.hpp b/src/boost/libs/spirit/example/support/utree/sexpr_generator.hpp
new file mode 100644
index 00000000..5dc56223
--- /dev/null
+++ b/src/boost/libs/spirit/example/support/utree/sexpr_generator.hpp
@@ -0,0 +1,128 @@
+/*==============================================================================
+ Copyright (c) 2001-2011 Hartmut Kaiser
+ Copyright (c) 2010-2011 Bryce Lelbach
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file BOOST_LICENSE_1_0.rst or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#if !defined(BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_GENERATOR_HPP)
+#define BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_GENERATOR_HPP
+
+#include <boost/spirit/include/support_utree.hpp>
+#include <boost/spirit/include/karma.hpp>
+
+namespace boost {
+namespace spirit {
+namespace traits {
+
+template<>
+struct transform_attribute<utree::nil_type, unused_type, karma::domain> {
+ typedef unused_type type;
+
+ static unused_type pre (utree::nil_type&) { return unused_type(); }
+};
+
+} // traits
+} // spirit
+} // boost
+
+namespace sexpr
+{
+
+namespace karma = boost::spirit::karma;
+namespace standard = boost::spirit::standard;
+
+using boost::spirit::utree;
+using boost::spirit::utf8_symbol_range_type;
+using boost::spirit::utf8_string_range_type;
+using boost::spirit::binary_range_type;
+
+struct bool_output_policies : karma::bool_policies<>
+{
+ template <typename CharEncoding, typename Tag, typename Iterator>
+ static bool generate_true(Iterator& sink, bool)
+ {
+ return string_inserter<CharEncoding, Tag>::call(sink, "#t");
+ }
+
+ template <typename CharEncoding, typename Tag, typename Iterator>
+ static bool generate_false(Iterator& sink, bool)
+ {
+ return string_inserter<CharEncoding, Tag>::call(sink, "#f");
+ }
+};
+
+template <typename Iterator>
+struct generator : karma::grammar<Iterator, utree()>
+{
+ typedef boost::iterator_range<utree::const_iterator> utree_list;
+
+ karma::rule<Iterator, utree()>
+ start, ref_;
+
+ karma::rule<Iterator, utree_list()>
+ list;
+
+ karma::rule<Iterator, utf8_symbol_range_type()>
+ symbol;
+
+ karma::rule<Iterator, utree::nil_type()>
+ nil_;
+
+ karma::rule<Iterator, utf8_string_range_type()>
+ utf8;
+
+ karma::rule<Iterator, binary_range_type()>
+ binary;
+
+ generator() : generator::base_type(start)
+ {
+ using standard::char_;
+ using standard::string;
+ using karma::bool_generator;
+ using karma::uint_generator;
+ using karma::double_;
+ using karma::int_;
+ using karma::lit;
+ using karma::right_align;
+
+ uint_generator<unsigned char, 16> hex2;
+ bool_generator<bool, bool_output_policies> boolean;
+
+ start = nil_
+ | double_
+ | int_
+ | boolean
+ | utf8
+ | symbol
+ | binary
+ | list
+ | ref_;
+
+ ref_ = start;
+
+ list = '(' << -(start % ' ') << ')';
+
+ utf8 = '"' << *(&char_('"') << "\\\"" | char_) << '"';
+
+ symbol = string;
+
+ binary = '#' << *right_align(2, '0')[hex2] << '#';
+
+ nil_ = karma::attr_cast(lit("nil"));
+
+ start.name("sexpr");
+ ref_.name("ref");
+ list.name("list");
+ utf8.name("string");
+ symbol.name("symbol");
+ binary.name("binary");
+ nil_.name("nil");
+ }
+};
+
+} // sexpr
+
+#endif // BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_GENERATOR_HPP
+
diff --git a/src/boost/libs/spirit/example/support/utree/sexpr_parser.hpp b/src/boost/libs/spirit/example/support/utree/sexpr_parser.hpp
new file mode 100644
index 00000000..15dfdfbd
--- /dev/null
+++ b/src/boost/libs/spirit/example/support/utree/sexpr_parser.hpp
@@ -0,0 +1,250 @@
+/*==============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2010-2011 Bryce Lelbach
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file BOOST_LICENSE_1_0.rst or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#if !defined(BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_PARSER_HPP)
+#define BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_PARSER_HPP
+
+#include "utf8_parser.hpp"
+#include "error_handler.hpp"
+
+namespace boost {
+namespace spirit {
+namespace traits {
+
+template<>
+struct transform_attribute<utree::nil_type, unused_type, qi::domain> {
+ typedef unused_type type;
+
+ static unused_type pre (utree::nil_type&) { return unused_type(); }
+ static void post (utree::nil_type&, unused_type) { }
+ static void fail (utree::nil_type&) { }
+};
+
+} // traits
+} // spirit
+} // boost
+
+namespace sexpr
+{
+
+namespace qi = boost::spirit::qi;
+namespace px = boost::phoenix;
+namespace standard = boost::spirit::standard;
+
+using boost::spirit::utree;
+using boost::spirit::utf8_symbol_type;
+using boost::spirit::utf8_string_type;
+using boost::spirit::binary_string_type;
+
+struct bool_input_policies
+{
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse_true(Iterator& first, Iterator const& last, Attribute& attr)
+ {
+ using boost::spirit::qi::detail::string_parse;
+ using boost::spirit::qi::bool_policies;
+ using boost::spirit::qi::unused;
+ using boost::spirit::traits::assign_to;
+ if (string_parse("#t", first, last, unused))
+ {
+ assign_to(true, attr); // result is true
+ return true;
+ }
+ return bool_policies<bool>::parse_true(first, last, attr);
+ }
+
+ template <typename Iterator, typename Attribute>
+ static bool
+ parse_false(Iterator& first, Iterator const& last, Attribute& attr)
+ {
+ using boost::spirit::qi::detail::string_parse;
+ using boost::spirit::qi::bool_policies;
+ using boost::spirit::qi::unused;
+ using boost::spirit::traits::assign_to;
+ if (string_parse("#f", first, last, unused))
+ {
+ assign_to(false, attr); // result is false
+ return true;
+ }
+ return bool_policies<bool>::parse_false(first, last, attr);
+ }
+};
+
+struct save_line_pos
+{
+ template <typename, typename>
+ struct result
+ {
+ typedef void type;
+ };
+
+ template <typename Range>
+ void operator()(utree& ast, Range const& rng) const
+ {
+ using boost::spirit::get_line;
+ std::size_t n = get_line(rng.begin());
+ if (n != -1)
+ {
+ BOOST_ASSERT(n <= (std::numeric_limits<short>::max)());
+ ast.tag(n);
+ }
+ else
+ ast.tag(-1);
+ }
+};
+
+template <typename Iterator, typename F>
+struct tagger : qi::grammar<Iterator, void(utree&, char)>
+{
+ qi::rule<Iterator, void(utree&, char)>
+ start;
+
+ qi::rule<Iterator, void(utree&)>
+ epsilon;
+
+ px::function<F>
+ f;
+
+ tagger(F f_ = F()) : tagger::base_type(start), f(f_)
+ {
+ using qi::omit;
+ using qi::raw;
+ using qi::eps;
+ using qi::lit;
+ using qi::_1;
+ using qi::_r1;
+ using qi::_r2;
+
+ start = omit[raw[lit(_r2)] [f(_r1, _1)]];
+
+ epsilon = omit[raw[eps] [f(_r1, _1)]];
+ }
+};
+
+template <typename Iterator>
+struct whitespace : qi::grammar<Iterator> {
+ qi::rule<Iterator>
+ start;
+
+ whitespace() : whitespace::base_type(start)
+ {
+ using standard::space;
+ using standard::char_;
+ using qi::eol;
+
+ start = space | (';' >> *(char_ - eol) >> eol);
+ }
+};
+
+} // sexpr
+
+//[utree_sexpr_parser
+namespace sexpr
+{
+
+template <typename Iterator, typename ErrorHandler = error_handler<Iterator> >
+struct parser : qi::grammar<Iterator, utree(), whitespace<Iterator> >
+{
+ qi::rule<Iterator, utree(), whitespace<Iterator> >
+ start, element, list;
+
+ qi::rule<Iterator, utree()>
+ atom;
+
+ qi::rule<Iterator, int()>
+ integer;
+
+ qi::rule<Iterator, utf8_symbol_type()>
+ symbol;
+
+ qi::rule<Iterator, utree::nil_type()>
+ nil_;
+
+ qi::rule<Iterator, binary_string_type()>
+ binary;
+
+ utf8::parser<Iterator>
+ string;
+
+ px::function<ErrorHandler> const
+ error;
+
+ tagger<Iterator, save_line_pos>
+ pos;
+
+ parser(std::string const& source_file = "<string>"):
+ parser::base_type(start), error(ErrorHandler(source_file))
+ {
+ using standard::char_;
+ using qi::unused_type;
+ using qi::lexeme;
+ using qi::hex;
+ using qi::oct;
+ using qi::no_case;
+ using qi::real_parser;
+ using qi::strict_real_policies;
+ using qi::uint_parser;
+ using qi::bool_parser;
+ using qi::on_error;
+ using qi::fail;
+ using qi::int_;
+ using qi::lit;
+ using qi::_val;
+ using qi::_1;
+ using qi::_2;
+ using qi::_3;
+ using qi::_4;
+
+ real_parser<double, strict_real_policies<double> > strict_double;
+ uint_parser<unsigned char, 16, 2, 2> hex2;
+ bool_parser<bool, sexpr::bool_input_policies> boolean;
+
+ start = element.alias();
+
+ element = atom | list;
+
+ list = pos(_val, '(') > *element > ')';
+
+ atom = nil_
+ | strict_double
+ | integer
+ | boolean
+ | string
+ | symbol
+ | binary;
+
+ nil_ = qi::attr_cast(lit("nil"));
+
+ integer = lexeme[ no_case["#x"] > hex]
+ | lexeme[ no_case["#o"] >> oct]
+ | lexeme[-no_case["#d"] >> int_];
+
+ std::string exclude = std::string(" ();\"\x01-\x1f\x7f") + '\0';
+ symbol = lexeme[+(~char_(exclude))];
+
+ binary = lexeme['#' > *hex2 > '#'];
+
+ start.name("sexpr");
+ element.name("element");
+ list.name("list");
+ atom.name("atom");
+ nil_.name("nil");
+ integer.name("integer");
+ symbol.name("symbol");
+ binary.name("binary");
+
+ on_error<fail>(start, error(_1, _2, _3, _4));
+ }
+};
+
+} // sexpr
+//]
+
+#endif // BOOST_SPIRIT_UTREE_EXAMPLE_SEXPR_PARSER_HPP
+
diff --git a/src/boost/libs/spirit/example/support/utree/utf8_parser.hpp b/src/boost/libs/spirit/example/support/utree/utf8_parser.hpp
new file mode 100644
index 00000000..b06046ae
--- /dev/null
+++ b/src/boost/libs/spirit/example/support/utree/utf8_parser.hpp
@@ -0,0 +1,138 @@
+/*==============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ Copyright (c) 2010-2011 Bryce Lelbach
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file BOOST_LICENSE_1_0.rst or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#if !defined(BOOST_SPIRIT_UTREE_EXAMPLE_UTF8_PARSER_HPP)
+#define BOOST_SPIRIT_UTREE_EXAMPLE_UTF8_PARSER_HPP
+
+#include <string>
+
+#include <boost/cstdint.hpp>
+
+#include <boost/regex/pending/unicode_iterator.hpp>
+
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_container.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/support_utree.hpp>
+
+namespace utf8
+{
+
+namespace qi = boost::spirit::qi;
+namespace px = boost::phoenix;
+namespace standard = boost::spirit::standard;
+
+using boost::spirit::utree;
+using boost::spirit::utf8_symbol_type;
+using boost::spirit::utf8_string_type;
+using boost::spirit::binary_string_type;
+
+typedef boost::uint32_t uchar;
+
+struct push_string
+{
+ template <typename, typename>
+ struct result
+ {
+ typedef void type;
+ };
+
+ void operator()(std::string& s, uchar code_point) const
+ {
+ typedef std::back_insert_iterator<std::string> insert_iter;
+ insert_iter out_iter(s);
+ boost::utf8_output_iterator<insert_iter> s_iter(out_iter);
+ *s_iter++ = code_point;
+ }
+};
+
+struct push_escaped_string
+{
+ template <typename, typename>
+ struct result
+ {
+ typedef void type;
+ };
+
+ void operator()(std::string& s, uchar c) const
+ {
+ switch (c) {
+ case 'b':
+ s += '\b';
+ break;
+ case 't':
+ s += '\t';
+ break;
+ case 'n':
+ s += '\n';
+ break;
+ case 'f':
+ s += '\f';
+ break;
+ case 'r':
+ s += '\r';
+ break;
+ case '"':
+ s += '"';
+ break;
+ case '\\':
+ s += '\\';
+ break;
+ }
+ }
+};
+
+template <typename Iterator>
+struct parser : qi::grammar<Iterator, std::string()>
+{
+ qi::rule<Iterator, void(std::string&)>
+ escaped;
+
+ qi::rule<Iterator, std::string()>
+ start;
+
+ px::function<push_string>
+ push_str;
+
+ px::function<push_escaped_string>
+ push_esc;
+
+ parser() : parser::base_type (start)
+ {
+ using standard::char_;
+ using qi::uint_parser;
+ using qi::_val;
+ using qi::_r1;
+ using qi::_1;
+
+ uint_parser<uchar, 16, 4, 4> hex4;
+ uint_parser<uchar, 16, 8, 8> hex8;
+
+ escaped
+ = '\\'
+ > ( ('u' > hex4) [push_str(_r1, _1)]
+ | ('U' > hex8) [push_str(_r1, _1)]
+ | char_("btnfr\\\"'") [push_esc(_r1, _1)]
+ );
+
+ start
+ = '"'
+ > *(escaped(_val) | (~char_('"')) [_val += _1])
+ > '"';
+
+ escaped.name("escaped_string");
+ start.name("string");
+ }
+};
+
+} // utf8
+
+#endif // BOOST_SPIRIT_UTREE_EXAMPLE_UTF8_PARSER_HPP
+