summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/spirit/repository/example
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/repository/example
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/repository/example')
-rw-r--r--src/boost/libs/spirit/repository/example/karma/Jamfile16
-rw-r--r--src/boost/libs/spirit/repository/example/karma/calc2_ast.hpp179
-rw-r--r--src/boost/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp181
-rw-r--r--src/boost/libs/spirit/repository/example/karma/confix.cpp63
-rw-r--r--src/boost/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp235
-rw-r--r--src/boost/libs/spirit/repository/example/qi/Jamfile23
-rw-r--r--src/boost/libs/spirit/repository/example/qi/advance.cpp110
-rw-r--r--src/boost/libs/spirit/repository/example/qi/calc1_sr.cpp118
-rw-r--r--src/boost/libs/spirit/repository/example/qi/confix.cpp113
-rw-r--r--src/boost/libs/spirit/repository/example/qi/derived.cpp158
-rw-r--r--src/boost/libs/spirit/repository/example/qi/distinct.cpp60
-rw-r--r--src/boost/libs/spirit/repository/example/qi/flush_multi_pass.cpp98
-rw-r--r--src/boost/libs/spirit/repository/example/qi/flush_multi_pass.txt8
-rw-r--r--src/boost/libs/spirit/repository/example/qi/iter_pos_parser.cpp51
-rw-r--r--src/boost/libs/spirit/repository/example/qi/keywords.cpp214
-rw-r--r--src/boost/libs/spirit/repository/example/qi/mini_xml2_sr.cpp246
-rw-r--r--src/boost/libs/spirit/repository/example/qi/options.cpp122
-rw-r--r--src/boost/libs/spirit/repository/example/qi/seek.cpp48
18 files changed, 2043 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/repository/example/karma/Jamfile b/src/boost/libs/spirit/repository/example/karma/Jamfile
new file mode 100644
index 00000000..b52e3b80
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/karma/Jamfile
@@ -0,0 +1,16 @@
+#==============================================================================
+# Copyright (c) 2009 Chris Hoeppler
+#
+# 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_v2_repository/example_karma
+ : requirements
+ <c++-template-depth>300
+ ;
+
+exe karma_confix : confix.cpp ;
+exe calc2_ast_dump_sr : calc2_ast_dump_sr.cpp ;
+exe mini_xml_karma_sr : mini_xml_karma_sr.cpp ;
+
diff --git a/src/boost/libs/spirit/repository/example/karma/calc2_ast.hpp b/src/boost/libs/spirit/repository/example/karma/calc2_ast.hpp
new file mode 100644
index 00000000..53fadf76
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/karma/calc2_ast.hpp
@@ -0,0 +1,179 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2001-2012 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A Calculator example demonstrating generation of AST which gets dumped into
+// a human readable format afterwards.
+//
+// [ JDG April 28, 2008 ]
+// [ HK April 28, 2008 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#if !defined(SPIRIT_EXAMPLE_CALC2_AST_APR_30_2008_1011AM)
+#define SPIRIT_EXAMPLE_CALC2_AST_APR_30_2008_1011AM
+
+#include <boost/variant.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_function.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/include/support_attributes_fwd.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// Our AST
+///////////////////////////////////////////////////////////////////////////////
+struct binary_op;
+struct unary_op;
+struct nil {};
+
+struct expression_ast
+{
+ typedef
+ boost::variant<
+ nil // can't happen!
+ , int
+ , boost::recursive_wrapper<binary_op>
+ , boost::recursive_wrapper<unary_op>
+ >
+ type;
+
+ // expose variant types
+ typedef type::types types;
+
+ // expose variant functionality
+ int which() const { return expr.which(); }
+
+ // constructors
+ expression_ast()
+ : expr(nil()) {}
+
+ expression_ast(unary_op const& expr)
+ : expr(expr) {}
+
+ expression_ast(binary_op const& expr)
+ : expr(expr) {}
+
+ expression_ast(unsigned int expr)
+ : expr(expr) {}
+
+ expression_ast(type const& expr)
+ : expr(expr) {}
+
+ expression_ast& operator+=(expression_ast const& rhs);
+ expression_ast& operator-=(expression_ast const& rhs);
+ expression_ast& operator*=(expression_ast const& rhs);
+ expression_ast& operator/=(expression_ast const& rhs);
+
+ type expr;
+};
+
+// expose variant functionality
+namespace boost
+{
+ // this function has to live in namespace boost for ADL to correctly find it
+ template <typename T>
+ inline T get(expression_ast const& expr)
+ {
+ return boost::get<T>(expr.expr);
+ }
+
+ // the specialization below tells Spirit to handle expression_ast as if it
+ // where a 'real' variant
+ namespace spirit { namespace traits
+ {
+ // the specialization below tells Spirit to handle expression_ast as
+ // if it where a 'real' variant (if used with Spirit.Karma)
+ template <>
+ struct not_is_variant<expression_ast, karma::domain>
+ : mpl::false_ {};
+
+ // the specialization of variant_which allows to generically extract
+ // the current type stored in the given variant like type
+ template <>
+ struct variant_which<expression_ast>
+ {
+ static int call(expression_ast const& v)
+ {
+ return v.which();
+ }
+ };
+ }}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+struct binary_op
+{
+ binary_op() {}
+
+ binary_op(
+ char op
+ , expression_ast const& left
+ , expression_ast const& right)
+ : op(op), left(left), right(right) {}
+
+ char op;
+ expression_ast left;
+ expression_ast right;
+};
+
+struct unary_op
+{
+ unary_op(
+ char op
+ , expression_ast const& right)
+ : op(op), right(right) {}
+
+ char op;
+ expression_ast right;
+};
+
+inline expression_ast& expression_ast::operator+=(expression_ast const& rhs)
+{
+ expr = binary_op('+', expr, rhs);
+ return *this;
+}
+
+inline expression_ast& expression_ast::operator-=(expression_ast const& rhs)
+{
+ expr = binary_op('-', expr, rhs);
+ return *this;
+}
+
+inline expression_ast& expression_ast::operator*=(expression_ast const& rhs)
+{
+ expr = binary_op('*', expr, rhs);
+ return *this;
+}
+
+inline expression_ast& expression_ast::operator/=(expression_ast const& rhs)
+{
+ expr = binary_op('/', expr, rhs);
+ return *this;
+}
+
+// We should be using expression_ast::operator-. There's a bug
+// in phoenix type deduction mechanism that prevents us from
+// doing so. Phoenix will be switching to BOOST_TYPEOF. In the
+// meantime, we will use a phoenix::function below:
+template <char Op>
+struct unary_expr
+{
+ template <typename T>
+ struct result { typedef T type; };
+
+ expression_ast operator()(expression_ast const& expr) const
+ {
+ return unary_op(Op, expr);
+ }
+};
+
+boost::phoenix::function<unary_expr<'+'> > pos;
+boost::phoenix::function<unary_expr<'-'> > neg;
+
+#endif
diff --git a/src/boost/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp b/src/boost/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp
new file mode 100644
index 00000000..12f18931
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/karma/calc2_ast_dump_sr.cpp
@@ -0,0 +1,181 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2001-2010 Hartmut Kaiser
+ Copyright (c) 2009 Francois Barel
+
+ 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A Calculator example demonstrating generation of AST which gets dumped into
+// a human readable format afterwards.
+//
+// [ JDG April 28, 2008 ]
+// [ HK April 28, 2008 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/config/warning_disable.hpp>
+
+#include <iostream>
+#include <vector>
+#include <string>
+
+#include "calc2_ast.hpp"
+
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/karma.hpp>
+#include <boost/spirit/repository/include/karma_subrule.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+
+using namespace boost::spirit;
+using namespace boost::spirit::ascii;
+namespace repo = boost::spirit::repository;
+
+///////////////////////////////////////////////////////////////////////////////
+// Our calculator parser grammar
+///////////////////////////////////////////////////////////////////////////////
+template <typename Iterator>
+struct calculator
+ : qi::grammar<Iterator, expression_ast(), space_type>
+{
+ calculator() : calculator::base_type(expression)
+ {
+ expression =
+ term [_val = _1]
+ >> *( ('+' >> term [_val += _1])
+ | ('-' >> term [_val -= _1])
+ )
+ ;
+
+ term =
+ factor [_val = _1]
+ >> *( ('*' >> factor [_val *= _1])
+ | ('/' >> factor [_val /= _1])
+ )
+ ;
+
+ factor =
+ uint_ [_val = _1]
+ | '(' >> expression [_val = _1] >> ')'
+ | ('-' >> factor [_val = neg(_1)])
+ | ('+' >> factor [_val = pos(_1)])
+ ;
+ }
+
+ qi::rule<Iterator, expression_ast(), space_type> expression, term, factor;
+};
+
+// We need to tell fusion about our binary_op and unary_op structs
+// to make them a first-class fusion citizen
+//
+// Note: we register the members exactly in the same sequence as we need them
+// in the grammar
+BOOST_FUSION_ADAPT_STRUCT(
+ binary_op,
+ (expression_ast, left)
+ (char, op)
+ (expression_ast, right)
+)
+
+BOOST_FUSION_ADAPT_STRUCT(
+ unary_op,
+ (char, op)
+ (expression_ast, right)
+)
+
+///////////////////////////////////////////////////////////////////////////////
+// Our AST grammar for the generator, this just dumps the AST as a expression
+///////////////////////////////////////////////////////////////////////////////
+template <typename OuputIterator>
+struct dump_ast
+ : karma::grammar<OuputIterator, expression_ast(), space_type>
+{
+ dump_ast() : dump_ast::base_type(entry)
+ {
+ //[calc2_ast_dump_sr_def
+ entry %= (
+ ast_node %= int_ | binary_node | unary_node
+
+ , binary_node %= '(' << ast_node << char_ << ast_node << ')'
+
+ , unary_node %= '(' << char_ << ast_node << ')'
+ );
+ //]
+ }
+
+ karma::rule<OuputIterator, expression_ast(), space_type> entry;
+
+ repo::karma::subrule<0, expression_ast()> ast_node;
+ repo::karma::subrule<1, binary_op()> binary_node;
+ repo::karma::subrule<2, unary_op()> unary_node;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Main program
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "Dump AST's for simple expressions...\n\n";
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ // Our parser grammar definitions
+ typedef std::string::const_iterator iterator_type;
+ typedef calculator<iterator_type> calculator;
+
+ calculator calc;
+
+ // Our generator grammar definitions
+ typedef std::back_insert_iterator<std::string> output_iterator_type;
+ typedef dump_ast<output_iterator_type> dump_ast;
+
+ dump_ast ast_grammar;
+
+ std::string str;
+ while (std::getline(std::cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ expression_ast ast;
+ std::string::const_iterator iter = str.begin();
+ std::string::const_iterator end = str.end();
+ bool r = qi::phrase_parse(iter, end, calc, space, ast);
+
+ if (r && iter == end)
+ {
+ std::string generated;
+ output_iterator_type outit(generated);
+ r = karma::generate_delimited(outit, ast_grammar, space, ast);
+
+ if (r)
+ {
+ std::cout << "Got AST:" << std::endl << generated
+ << std::endl;
+ std::cout << "-------------------------\n";
+ }
+ else
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Generating failed\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/repository/example/karma/confix.cpp b/src/boost/libs/spirit/repository/example/karma/confix.cpp
new file mode 100644
index 00000000..4ea6f21c
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/karma/confix.cpp
@@ -0,0 +1,63 @@
+// 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)
+
+// The purpose of this example is to demonstrate different use cases for the
+// confix generator.
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+//[karma_confix_includes
+#include <boost/spirit/include/karma.hpp>
+#include <boost/spirit/repository/include/karma_confix.hpp>
+//]
+
+//[karma_confix_namespace
+using namespace boost::spirit;
+using namespace boost::spirit::ascii;
+using boost::spirit::repository::confix;
+//]
+
+int main()
+{
+//[karma_confix_cpp_comment
+ // C++ comment
+ std::cout <<
+ karma::format_delimited(
+ confix("//", eol)[string], // format description
+ space, // delimiter
+ "This is a comment" // data
+ ) << std::endl;
+//]
+
+//[karma_confix_c_comment
+ // C comment
+ std::cout <<
+ karma::format_delimited(
+ confix("/*", "*/")[string], // format description
+ space, // delimiter
+ "This is a comment" // data
+ ) << std::endl;
+//]
+
+//[karma_confix_function
+ // Generate a function call with an arbitrary parameter list
+ std::vector<std::string> parameters;
+ parameters.push_back("par1");
+ parameters.push_back("par2");
+ parameters.push_back("par3");
+
+ std::cout <<
+ karma::format(
+ string << confix('(', ')')[string % ','], // format description
+ "func", // function name
+ parameters // parameter names
+ ) << std::endl;
+//]
+
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp b/src/boost/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp
new file mode 100644
index 00000000..677cb263
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/karma/mini_xml_karma_sr.cpp
@@ -0,0 +1,235 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2001-2010 Hartmut Kaiser
+ Copyright (c) 2009 Francois Barel
+
+ 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A mini XML-like parser, Karma is used to print out the generated AST
+//
+// [ JDG March 25, 2007 ] spirit2
+// [ HK April 02, 2007 ] spirit2
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
+
+#include <boost/spirit/include/qi.hpp>
+//[mini_xml_karma_sr_includes
+#include <boost/spirit/include/karma.hpp>
+#include <boost/spirit/repository/include/karma_subrule.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_fusion.hpp>
+//]
+#include <boost/spirit/include/phoenix_function.hpp>
+#include <boost/spirit/include/phoenix_stl.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/variant/recursive_variant.hpp>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+//[mini_xml_karma_sr_using
+using namespace boost::spirit;
+using namespace boost::spirit::ascii;
+namespace repo = boost::spirit::repository;
+//]
+
+namespace fusion = boost::fusion;
+namespace phoenix = boost::phoenix;
+
+using phoenix::at_c;
+using phoenix::push_back;
+
+///////////////////////////////////////////////////////////////////////////////
+// Our mini XML tree representation
+///////////////////////////////////////////////////////////////////////////////
+struct mini_xml;
+
+typedef
+ boost::variant<
+ boost::recursive_wrapper<mini_xml>
+ , std::string
+ >
+mini_xml_node;
+
+struct mini_xml
+{
+ std::string name; // tag name
+ std::vector<mini_xml_node> children; // children
+};
+
+// We need to tell fusion about our mini_xml struct
+// to make it a first-class fusion citizen
+BOOST_FUSION_ADAPT_STRUCT(
+ mini_xml,
+ (std::string, name)
+ (std::vector<mini_xml_node>, children)
+)
+
+///////////////////////////////////////////////////////////////////////////////
+// Our mini XML grammar definition
+///////////////////////////////////////////////////////////////////////////////
+template <typename Iterator>
+struct mini_xml_parser :
+ qi::grammar<Iterator, mini_xml(), space_type>
+{
+ mini_xml_parser() : mini_xml_parser::base_type(xml)
+ {
+ text = lexeme[+(char_ - '<') [_val += _1]];
+ node = (xml | text) [_val = _1];
+
+ start_tag =
+ '<'
+ >> !lit('/')
+ >> lexeme[+(char_ - '>') [_val += _1]]
+ >> '>'
+ ;
+
+ end_tag =
+ "</"
+ >> lit(_r1)
+ >> '>'
+ ;
+
+ xml =
+ start_tag [at_c<0>(_val) = _1]
+ >> *node [push_back(at_c<1>(_val), _1)]
+ >> end_tag(at_c<0>(_val))
+ ;
+ }
+
+ qi::rule<Iterator, mini_xml(), space_type> xml;
+ qi::rule<Iterator, mini_xml_node(), space_type> node;
+ qi::rule<Iterator, std::string(), space_type> text;
+ qi::rule<Iterator, std::string(), space_type> start_tag;
+ qi::rule<Iterator, void(std::string), space_type> end_tag;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// A couple of phoenix functions helping to access the elements of the
+// generated AST
+///////////////////////////////////////////////////////////////////////////////
+template <typename T>
+struct get_element
+{
+ template <typename T1>
+ struct result { typedef T const& type; };
+
+ T const& operator()(mini_xml_node const& node) const
+ {
+ return boost::get<T>(node);
+ }
+};
+
+phoenix::function<get_element<std::string> > _string;
+phoenix::function<get_element<mini_xml> > _xml;
+
+///////////////////////////////////////////////////////////////////////////////
+// The output grammar defining the format of the generated data
+///////////////////////////////////////////////////////////////////////////////
+//[mini_xml_karma_sr_grammar
+template <typename OutputIterator>
+struct mini_xml_generator
+ : karma::grammar<OutputIterator, mini_xml()>
+{
+ mini_xml_generator() : mini_xml_generator::base_type(entry)
+ {
+ entry %= (
+ xml =
+ '<' << string[_1 = at_c<0>(_val)] << '>'
+ << (*node)[_1 = at_c<1>(_val)]
+ << "</" << string[_1 = at_c<0>(_val)] << '>'
+
+ , node %= string | xml
+ );
+ }
+
+ karma::rule<OutputIterator, mini_xml()> entry;
+
+ repo::karma::subrule<0, mini_xml()> xml;
+ repo::karma::subrule<1, mini_xml_node()> node;
+};
+//]
+
+///////////////////////////////////////////////////////////////////////////////
+// Main program
+///////////////////////////////////////////////////////////////////////////////
+int main(int argc, char **argv)
+{
+ char const* filename;
+ if (argc > 1)
+ {
+ filename = argv[1];
+ }
+ else
+ {
+ std::cerr << "Error: No input file provided." << std::endl;
+ return 1;
+ }
+
+ std::ifstream in(filename, std::ios_base::in);
+
+ if (!in)
+ {
+ std::cerr << "Error: Could not open input file: "
+ << filename << std::endl;
+ return 1;
+ }
+
+ std::string storage; // We will read the contents here.
+ in.unsetf(std::ios::skipws); // No white space skipping!
+ std::copy(
+ std::istream_iterator<char>(in),
+ std::istream_iterator<char>(),
+ std::back_inserter(storage));
+
+ typedef mini_xml_parser<std::string::const_iterator> mini_xml_parser;
+ mini_xml_parser xmlin; // Our grammar definition
+ mini_xml ast; // our tree
+
+ std::string::const_iterator iter = storage.begin();
+ std::string::const_iterator end = storage.end();
+ bool r = qi::phrase_parse(iter, end, xmlin, space, ast);
+
+ if (r && iter == end)
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing succeeded\n";
+ std::cout << "-------------------------\n";
+
+ typedef std::back_insert_iterator<std::string> outiter_type;
+ typedef mini_xml_generator<outiter_type> mini_xml_generator;
+
+ mini_xml_generator xmlout; // Our grammar definition
+
+ std::string generated;
+ outiter_type outit(generated);
+ bool r = karma::generate(outit, xmlout, ast);
+
+ if (r)
+ std::cout << generated << std::endl;
+ return 0;
+ }
+ else
+ {
+ std::string::const_iterator begin = storage.begin();
+ std::size_t dist = std::distance(begin, iter);
+ std::string::const_iterator some =
+ iter + (std::min)(storage.size()-dist, std::size_t(30));
+ std::string context(iter, some);
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing failed\n";
+ std::cout << "stopped at: \": " << context << "...\"\n";
+ std::cout << "-------------------------\n";
+ return 1;
+ }
+}
+
+
diff --git a/src/boost/libs/spirit/repository/example/qi/Jamfile b/src/boost/libs/spirit/repository/example/qi/Jamfile
new file mode 100644
index 00000000..1857b318
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/Jamfile
@@ -0,0 +1,23 @@
+#==============================================================================
+# Copyright (c) 2001-2009 Joel de Guzman
+# 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)
+#==============================================================================
+
+project spirit_v2_repository/example_qi
+ : requirements
+ <c++-template-depth>300
+ ;
+
+exe qi_confix : confix.cpp ;
+exe qi_distinct : distinct.cpp ;
+exe flush_multi_pass : flush_multi_pass.cpp ;
+exe calc1_sr : calc1_sr.cpp ;
+exe mini_xml2_sr : mini_xml2_sr.cpp ;
+exe advance : advance.cpp ;
+exe keywords : keywords.cpp ;
+exe derived : derived.cpp ;
+exe options : options.cpp ;
+exe seek : seek.cpp ;
diff --git a/src/boost/libs/spirit/repository/example/qi/advance.cpp b/src/boost/libs/spirit/repository/example/qi/advance.cpp
new file mode 100644
index 00000000..e47d32ee
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/advance.cpp
@@ -0,0 +1,110 @@
+// Copyright (c) 2011 Aaron Graham
+//
+// 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)
+
+// The purpose of this example is to demonstrate the use of the advance parser.
+
+//[qi_advance_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/repository/include/qi_advance.hpp>
+//]
+
+#include <list>
+#include <string>
+
+//[qi_advance_namespaces
+namespace qi = boost::spirit::qi;
+using boost::spirit::repository::qi::advance;
+//]
+
+namespace client
+{
+ //[qi_advance_grammar
+ template <typename Iterator>
+ struct advance_grammar : qi::grammar<Iterator, qi::locals<int> >
+ {
+ advance_grammar() : advance_grammar::base_type(start)
+ {
+ using qi::byte_;
+ using qi::eoi;
+ using namespace qi::labels;
+
+ start
+ = byte_ [_a = _1]
+ >> advance(_a)
+ >> "boost"
+ >> byte_ [_a = _1]
+ >> (advance(_a) | "qi") // note alternative when advance fails
+ >> eoi
+ ;
+ }
+
+ qi::rule<Iterator, qi::locals<int> > start;
+ };
+ //]
+}
+
+int main()
+{
+ // This parser is tested with both random access iterators (std::string)
+ // and bidirectional iterators (std::list).
+ char const* result;
+
+ //[qi_advance_example1
+ unsigned char const alt1[] =
+ {
+ 5, // number of bytes to advance
+ 1, 2, 3, 4, 5, // data to advance through
+ 'b', 'o', 'o', 's', 't', // word to parse
+ 2, // number of bytes to advance
+ 11, 12 // more data to advance through
+ // eoi
+ };
+
+ std::string const alt1_string(alt1, alt1 + sizeof alt1);
+ std::list<unsigned char> const alt1_list(alt1, alt1 + sizeof alt1);
+
+ result =
+ qi::parse(alt1_string.begin(), alt1_string.end()
+ , client::advance_grammar<std::string::const_iterator>())
+ ? "succeeded" : "failed";
+ std::cout << "Parsing alt1 using random access iterator " << result << std::endl;
+
+ result =
+ qi::parse(alt1_list.begin(), alt1_list.end()
+ , client::advance_grammar<std::list<unsigned char>::const_iterator>())
+ ? "succeeded" : "failed";
+ std::cout << "Parsing alt1 using bidirectional iterator " << result << std::endl;
+ //]
+
+ //[qi_advance_example2
+ unsigned char const alt2[] =
+ {
+ 2, // number of bytes to advance
+ 1, 2, // data to advance through
+ 'b', 'o', 'o', 's', 't', // word to parse
+ 4, // number of bytes to advance
+ 'q', 'i' // alternative (advance won't work)
+ // eoi
+ };
+
+ std::string const alt2_string(alt2, alt2 + sizeof alt2);
+ std::list<unsigned char> const alt2_list(alt2, alt2 + sizeof alt2);
+
+ result =
+ qi::parse(alt2_string.begin(), alt2_string.end()
+ , client::advance_grammar<std::string::const_iterator>())
+ ? "succeeded" : "failed";
+ std::cout << "Parsing alt2 using random access iterator " << result << std::endl;
+
+ result =
+ qi::parse(alt2_list.begin(), alt2_list.end()
+ , client::advance_grammar<std::list<unsigned char>::const_iterator>())
+ ? "succeeded" : "failed";
+ std::cout << "Parsing alt2 using bidirectional iterator " << result << std::endl;
+ //]
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/calc1_sr.cpp b/src/boost/libs/spirit/repository/example/qi/calc1_sr.cpp
new file mode 100644
index 00000000..031a33f5
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/calc1_sr.cpp
@@ -0,0 +1,118 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2009 Francois Barel
+
+ 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Plain calculator example demonstrating the grammar. The parser is a
+// syntax checker only and does not do any semantic evaluation.
+//
+// [ JDG May 10, 2002 ] spirit1
+// [ JDG March 4, 2007 ] spirit2
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_subrule.hpp>
+#include <iostream>
+#include <string>
+
+namespace client
+{
+ namespace qi = boost::spirit::qi;
+ namespace repo = boost::spirit::repository;
+ namespace ascii = boost::spirit::ascii;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // Our calculator grammar
+ ///////////////////////////////////////////////////////////////////////////////
+ template <typename Iterator>
+ struct calculator : qi::grammar<Iterator, ascii::space_type>
+ {
+ calculator() : calculator::base_type(entry)
+ {
+ using qi::uint_;
+
+ //[calc1_sr_def
+ entry = (
+ expression =
+ term
+ >> *( ('+' >> term)
+ | ('-' >> term)
+ )
+
+ , term =
+ factor
+ >> *( ('*' >> factor)
+ | ('/' >> factor)
+ )
+
+ , factor =
+ uint_
+ | '(' >> expression >> ')'
+ | ('-' >> factor)
+ | ('+' >> factor)
+ );
+ //]
+ }
+
+ qi::rule<Iterator, ascii::space_type> entry;
+
+ repo::qi::subrule<0> expression;
+ repo::qi::subrule<1> term;
+ repo::qi::subrule<2> factor;
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Main program
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "Expression parser...\n\n";
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ using boost::spirit::ascii::space;
+ typedef std::string::const_iterator iterator_type;
+ typedef client::calculator<iterator_type> calculator;
+
+ calculator calc; // Our grammar
+
+ 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, calc, space);
+
+ 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/repository/example/qi/confix.cpp b/src/boost/libs/spirit/repository/example/qi/confix.cpp
new file mode 100644
index 00000000..2426e824
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/confix.cpp
@@ -0,0 +1,113 @@
+// Copyright (c) 2009 Chris Hoeppler
+//
+// 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)
+
+// The purpose of this example is to demonstrate different use cases for the
+// confix directive.
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+//[qi_confix_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_confix.hpp>
+//]
+
+namespace client {
+//[qi_confix_using
+ using boost::spirit::eol;
+ using boost::spirit::lexeme;
+ using boost::spirit::ascii::alnum;
+ using boost::spirit::ascii::char_;
+ using boost::spirit::ascii::space;
+ using boost::spirit::qi::parse;
+ using boost::spirit::qi::phrase_parse;
+ using boost::spirit::repository::confix;
+//]
+
+//[qi_confix_cpp_comment
+ template <typename Iterator>
+ bool parse_cpp_comment(Iterator first, Iterator last, std::string& attr)
+ {
+ bool r = parse(first, last,
+ confix("//", eol)[*(char_ - eol)], // grammar
+ attr); // attribute
+
+ if (!r || first != last) // fail if we did not get a full match
+ return false;
+ return r;
+ }
+//]
+
+//[qi_confix_c_comment
+ template <typename Iterator>
+ bool parse_c_comment(Iterator first, Iterator last, std::string& attr)
+ {
+ bool r = parse(first, last,
+ confix("/*", "*/")[*(char_ - "*/")], // grammar
+ attr); // attribute
+
+ if (!r || first != last) // fail if we did not get a full match
+ return false;
+ return r;
+ }
+//]
+
+//[qi_confix_tagged_data
+ template <typename Iterator>
+ bool parse_tagged(Iterator first, Iterator last, std::string& attr)
+ {
+ bool r = phrase_parse(first, last,
+ confix("<b>", "</b>")[lexeme[*(char_ - '<')]], // grammar
+ space, // skip
+ attr); // attribute
+
+ if (!r || first != last) // fail if we did not get a full match
+ return false;
+ return r;
+ }
+//]
+}
+
+
+int main()
+{
+ // C++ comment
+ std::string comment("// This is a comment\n");
+ std::string attr;
+ bool r = client::parse_cpp_comment(comment.begin(), comment.end(), attr);
+
+ std::cout << "Parsing a C++ comment";
+ if (r && attr == " This is a comment")
+ std::cout << " succeeded." << std::endl;
+ else
+ std::cout << " failed" << std::endl;
+
+ // C comment
+ comment = "/* This is another comment */";
+ attr.clear();
+ r = client::parse_c_comment(comment.begin(), comment.end(), attr);
+
+ std::cout << "Parsing a C comment";
+ if (r && attr == " This is another comment ")
+ std::cout << " succeeded." << std::endl;
+ else
+ std::cout << " failed" << std::endl;
+
+ // Tagged data
+ std::string data = "<b> This is the body. </b>";
+ attr.clear();
+
+ r = client::parse_tagged(data.begin(), data.end(), attr);
+
+ std::cout << "Parsing tagged data";
+ if (r && attr == "This is the body. ")
+ std::cout << " succeeded." << std::endl;
+ else
+ std::cout << " failed" << std::endl;
+
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/repository/example/qi/derived.cpp b/src/boost/libs/spirit/repository/example/qi/derived.cpp
new file mode 100644
index 00000000..a92490a9
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/derived.cpp
@@ -0,0 +1,158 @@
+/*=============================================================================
+ Copyright (c) 2011 Thomas Bernard
+ 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)
+=============================================================================*/
+//[reference_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_container.hpp>
+#include <boost/spirit/include/phoenix_object.hpp>
+#include <boost/spirit/include/phoenix_fusion.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/spirit/repository/include/qi_kwd.hpp>
+#include <boost/spirit/repository/include/qi_keywords.hpp>
+#include <iostream>
+#include <string>
+#include <cstdlib>
+#include <iterator>
+//]
+
+
+// Data structure definitions
+
+struct base_type {
+ base_type(const std::string &name) : name(name) {}
+ std::string name;
+
+ virtual std::ostream &output(std::ostream &os) const
+ {
+ os<<"Base : "<<name;
+ return os;
+ }
+
+};
+
+struct derived1 : public base_type {
+ derived1(const std::string &name, unsigned int data1) : base_type(name), data1(data1) {}
+ unsigned int data1;
+
+ virtual std::ostream &output(std::ostream &os) const
+ {
+ base_type::output(os);
+ os<<", "<<data1;
+ return os;
+ }
+
+};
+
+struct derived2 : public base_type {
+ derived2(const std::string &name, unsigned int data2) : base_type(name), data2(data2) {}
+ unsigned int data2;
+ virtual std::ostream &output(std::ostream &os) const
+ {
+ base_type::output(os);
+ os<<", "<<data2;
+ return os;
+ }
+
+};
+
+struct derived3 : public derived2 {
+ derived3(const std::string &name, unsigned int data2, double data3) :
+ derived2(name,data2),
+ data3(data3) {}
+ double data3;
+
+ virtual std::ostream &output(std::ostream &os) const
+ {
+ derived2::output(os);
+ os<<", "<<data3;
+ return os;
+ }
+
+
+};
+
+std::ostream &operator<<(std::ostream &os, const base_type &obj)
+{
+ return obj.output(os);
+}
+
+BOOST_FUSION_ADAPT_STRUCT( base_type,
+ (std::string, name)
+)
+
+BOOST_FUSION_ADAPT_STRUCT( derived1,
+ (std::string , name)
+ (unsigned int , data1)
+)
+BOOST_FUSION_ADAPT_STRUCT( derived2,
+ (std::string , name)
+ (unsigned int, data2)
+)
+BOOST_FUSION_ADAPT_STRUCT( derived3,
+ (std::string , name)
+ (unsigned int, data2)
+ (double, data3)
+)
+//]
+
+int
+main()
+{
+
+
+ using boost::spirit::repository::qi::kwd;
+ using boost::spirit::qi::inf;
+ using boost::spirit::ascii::space_type;
+ using boost::spirit::ascii::char_;
+ using boost::spirit::qi::double_;
+ using boost::spirit::qi::int_;
+ using boost::spirit::qi::rule;
+ using boost::spirit::_val;
+ using boost::spirit::_1;
+ using boost::spirit::_2;
+ using boost::spirit::_3;
+
+
+ //Rule declarations
+ rule<const char *, std::string(), space_type> parse_string;
+ rule<const char *, std::vector<base_type*>(), space_type> kwd_rule;
+
+ // Our string parsing helper
+ parse_string %= '"'> *(char_-'"') > '"';
+
+ namespace phx=boost::phoenix;
+ //[ kwd rule
+ kwd_rule =
+ kwd("derived1")[ ('=' > parse_string > int_ ) [phx::push_back(_val,phx::new_<derived1>(_1,_2))] ]
+ / kwd("derived2")[ ('=' > parse_string > int_ ) [phx::push_back(_val,phx::new_<derived2>(_1,_2))]]
+ / kwd("derived3")[ ('=' > parse_string > int_ > double_) [phx::push_back(_val,phx::new_<derived3>(_1,_2,_3))] ]
+ ;
+ //]
+
+ using boost::spirit::qi::phrase_parse;
+ using boost::spirit::qi::ascii::space;
+
+ // The result vector
+ std::vector<base_type*> result;
+
+ char const input[]="derived2 = \"object1\" 10 derived3= \"object2\" 40 20.0 ";
+ char const* f(input);
+ char const* l(f + strlen(f));
+
+ if (phrase_parse(f, l, kwd_rule, space,result) && (f == l))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+
+ using namespace boost::phoenix::arg_names;
+ std::for_each(result.begin(),result.end(),std::cout<<*arg1<<std::endl);
+ // Clean up the vector of pointers
+ std::for_each(result.begin(),result.end(),phx::delete_(arg1));
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/distinct.cpp b/src/boost/libs/spirit/repository/example/qi/distinct.cpp
new file mode 100644
index 00000000..78bac6ed
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/distinct.cpp
@@ -0,0 +1,60 @@
+// 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)
+
+// The purpose of this example is to demonstrate different use cases for the
+// distinct parser.
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+//[qi_distinct_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_distinct.hpp>
+//]
+
+//[qi_distinct_namespace
+using namespace boost::spirit;
+using namespace boost::spirit::ascii;
+using boost::spirit::repository::distinct;
+//]
+
+int main()
+{
+ //[qi_distinct_description_ident
+ {
+ std::string str("description ident");
+ std::string::iterator first(str.begin());
+ bool r = qi::phrase_parse(first, str.end()
+ , distinct(alnum | '_')["description"] >> -lit("--") >> +(alnum | '_')
+ , space);
+ BOOST_ASSERT(r && first == str.end());
+ }
+ //]
+
+ //[qi_distinct_description__ident
+ {
+ std::string str("description--ident");
+ std::string::iterator first(str.begin());
+ bool r = qi::phrase_parse(first, str.end()
+ , distinct(alnum | '_')["description"] >> -lit("--") >> +(alnum | '_')
+ , space);
+ BOOST_ASSERT(r && first == str.end());
+ }
+ //]
+
+ //[qi_distinct_description_ident_error
+ {
+ std::string str("description-ident");
+ std::string::iterator first(str.begin());
+ bool r = qi::phrase_parse(first, str.end()
+ , distinct(alnum | '_')["description"] >> -lit("--") >> +(alnum | '_')
+ , space);
+ BOOST_ASSERT(!r && first == str.begin());
+ }
+ //]
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.cpp b/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.cpp
new file mode 100644
index 00000000..79fa2e57
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.cpp
@@ -0,0 +1,98 @@
+// 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)
+
+// The purpose of this example is to demonstrate a simple use case for the
+// flush_multi_pass parser.
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+//[qi_flush_multi_pass_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_flush_multi_pass.hpp>
+//]
+
+//[qi_flush_multi_pass_namespace
+namespace spirit = boost::spirit;
+using boost::spirit::repository::flush_multi_pass;
+//]
+
+namespace client
+{
+ //[qi_flush_multi_pass_clear_buffer
+ template <typename Iterator, typename Skipper>
+ struct preprocessor : spirit::qi::grammar<Iterator, Skipper>
+ {
+ // This is a simplified preprocessor grammar recognizing
+ //
+ // #define MACRONAME something
+ // #undef MACRONAME
+ //
+ // Its sole purpose is to show an example how to use the
+ // flush_multi_pass parser. At the end of each line no backtracking can
+ // occur anymore so that it's safe to clear all internal buffers in the
+ // multi_pass.
+ preprocessor() : preprocessor::base_type(file)
+ {
+ using spirit::ascii::char_;
+ using spirit::qi::eol;
+ using spirit::qi::lit;
+
+ file =
+ *line
+ ;
+
+ line = ( command | *(char_ - eol) )
+ >> eol
+ >> flush_multi_pass
+ ;
+
+ command =
+ "#define" >> *lit(' ') >> *(char_ - ' ') >> *lit(' ') >> *(char_ - eol)
+ | "#undef" >> *lit(' ') >> *(char_ - eol)
+ ;
+ }
+
+ spirit::qi::rule<Iterator, Skipper> file, line, command;
+ };
+ //]
+}
+
+template <typename Iterator, typename Skipper>
+bool parse(Iterator& first, Iterator end, Skipper const& skipper)
+{
+ client::preprocessor<Iterator, Skipper> g;
+ return boost::spirit::qi::phrase_parse(first, end, g, skipper);
+}
+
+int main()
+{
+ namespace spirit = boost::spirit;
+ using spirit::ascii::char_;
+ using spirit::qi::eol;
+
+ std::ifstream in("flush_multi_pass.txt"); // we get our input from this file
+ if (!in.is_open()) {
+ std::cout << "Could not open input file: 'flush_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));
+ spirit::multi_pass<base_iterator_type> end =
+ spirit::make_default_multi_pass(base_iterator_type());
+
+ bool result = parse(first, end, '#' >> *(char_ - eol) >> eol);
+ 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/repository/example/qi/flush_multi_pass.txt b/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.txt
new file mode 100644
index 00000000..46cd92eb
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/flush_multi_pass.txt
@@ -0,0 +1,8 @@
+# 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)
+
+#define MACRO foo
+#undef MACRO
+
diff --git a/src/boost/libs/spirit/repository/example/qi/iter_pos_parser.cpp b/src/boost/libs/spirit/repository/example/qi/iter_pos_parser.cpp
new file mode 100644
index 00000000..28081405
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/iter_pos_parser.cpp
@@ -0,0 +1,51 @@
+// 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)
+
+// The purpose of this example is to show how a simple custom primitive parser
+// component can be written. We develop a custom parser exposing the current
+// iterator position as its attribute.
+//
+// For more information see: http://spirit.sourceforge.net/home/?page_id=567
+
+#include <boost/spirit/include/qi_parse_attr.hpp>
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_operator.hpp>
+#include <boost/spirit/repository/include/qi_iter_pos.hpp>
+
+#include <string>
+
+namespace qi = boost::spirit::qi;
+
+int main()
+{
+ using boost::spirit::repository::qi::iter_pos;
+
+ std::string prefix, suffix; // attributes receiving the
+ std::string::iterator position; // parsed values
+
+ std::string input("prefix1234567");
+ std::string::iterator first = input.begin();
+ bool result =
+ qi::parse(first, input.end()
+ , +qi::alpha >> iter_pos >> +qi::digit
+ , prefix, position, suffix);
+
+ if (result)
+ {
+ std::cout << "-------------------------------- \n";
+ std::cout << "Parsing succeeded\n";
+ std::cout << "prefix is: " << prefix << "\n";
+ std::cout << "suffix is: " << suffix << "\n";
+ std::cout << "position is: " << std::distance(input.begin(), position) << "\n";
+ std::cout << "-------------------------------- \n";
+ }
+ else
+ {
+ std::cout << "-------------------------------- \n";
+ std::cout << "Parsing failed\n";
+ std::cout << "-------------------------------- \n";
+ }
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/keywords.cpp b/src/boost/libs/spirit/repository/example/qi/keywords.cpp
new file mode 100644
index 00000000..51ea7353
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/keywords.cpp
@@ -0,0 +1,214 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ 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)
+=============================================================================*/
+//[reference_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/spirit/repository/include/qi_kwd.hpp>
+#include <boost/spirit/repository/include/qi_keywords.hpp>
+#include <iostream>
+#include <string>
+#include <cstdlib>
+#include <iterator>
+//]
+
+//[reference_test
+template <typename P>
+void test_parser(
+ char const* input, P const& p, bool full_match = true)
+{
+ using boost::spirit::qi::parse;
+
+ char const* f(input);
+ char const* l(f + strlen(f));
+ if (parse(f, l, p) && (!full_match || (f == l)))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+}
+
+template <typename P>
+void test_phrase_parser(
+ char const* input, P const& p, bool full_match = true)
+{
+ using boost::spirit::qi::phrase_parse;
+ using boost::spirit::qi::ascii::space;
+
+ char const* f(input);
+ char const* l(f + strlen(f));
+ if (phrase_parse(f, l, p, space) && (!full_match || (f == l)))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+}
+//]
+
+//[reference_test_attr
+template <typename P, typename T>
+void test_parser_attr(
+ char const* input, P const& p, T& attr, bool full_match = true)
+{
+ using boost::spirit::qi::parse;
+
+ char const* f(input);
+ char const* l(f + strlen(f));
+ if (parse(f, l, p, attr) && (!full_match || (f == l)))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+}
+
+template <typename P, typename T>
+void test_phrase_parser_attr(
+ char const* input, P const& p, T& attr, bool full_match = true)
+{
+ using boost::spirit::qi::phrase_parse;
+ using boost::spirit::qi::ascii::space;
+
+ char const* f(input);
+ char const* l(f + strlen(f));
+ if (phrase_parse(f, l, p, space, attr) && (!full_match || (f == l)))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+}
+//]
+
+
+
+//[reference_keyword_list_test_data_structure
+// Data structure definitions to test the kwd directive
+// and the keywords list operator
+
+struct person {
+ std::string name;
+ int age;
+ double size;
+ std::vector<std::string> favorite_colors;
+
+};
+
+std::ostream &operator<<(std::ostream &os, const person &p)
+{
+ os<<"Person : "<<p.name<<", "<<p.age<<", "<<p.size<<std::endl;
+ std::copy(p.favorite_colors.begin(),p.favorite_colors.end(),std::ostream_iterator<std::string>(os,"\n"));
+ return os;
+}
+
+BOOST_FUSION_ADAPT_STRUCT( person,
+ (std::string, name)
+ (int, age)
+ (double, size)
+ (std::vector<std::string>, favorite_colors)
+)
+//]
+
+int
+main()
+{
+
+ // keyword_list
+ {
+ //[reference_using_declarations_keyword_list
+ using boost::spirit::repository::qi::kwd;
+ using boost::spirit::qi::inf;
+ using boost::spirit::ascii::space_type;
+ using boost::spirit::ascii::char_;
+ using boost::spirit::qi::double_;
+ using boost::spirit::qi::int_;
+ using boost::spirit::qi::rule;
+ //]
+
+ //[reference_keyword_list_rule_declarations
+ rule<const char *, std::string(), space_type> parse_string;
+ rule<const char *, person(), space_type> no_constraint_person_rule, constraint_person_rule;
+
+ parse_string %= '"'> *(char_-'"') > '"';
+ //]
+
+ //[reference_keyword_list_no_constraint_rule
+ no_constraint_person_rule %=
+ kwd("name")['=' > parse_string ]
+ / kwd("age") ['=' > int_]
+ / kwd("size") ['=' > double_ > 'm']
+ ;
+ //]
+
+
+ //[reference_keyword_list
+ //`Parsing a keyword list:
+ // Let's declare a small list of people for which we want to collect information.
+ person John,Mary,Mike,Hellen,Johny;
+ test_phrase_parser_attr(
+ "name = \"John\" \n age = 10 \n size = 1.69m "
+ ,no_constraint_person_rule
+ ,John); // full in orginal order
+ std::cout<<John;
+
+ test_phrase_parser_attr(
+ "age = 10 \n size = 1.69m \n name = \"Mary\""
+ ,no_constraint_person_rule
+ ,Mary); // keyword oder doesn't matter
+ std::cout<<Mary;
+
+ test_phrase_parser_attr(
+ "size = 1.69m \n name = \"Mike\" \n age = 10 "
+ ,no_constraint_person_rule
+ ,Mike); // still the same result
+
+ std::cout<<Mike;
+
+ /*`The code above will print:[teletype]
+
+ Person : John, 10, 1.69
+ Person : Mary, 10, 1.69
+ Person : Mike, 10, 1.69
+ */
+ //]
+
+ //[reference_keyword_list_constraint_rule
+ /*`The parser definition below uses the kwd directive occurrence constraint variants to
+ make sure that the name and age keyword occur only once and allows the favorite color
+ entry to appear 0 or more times. */
+ constraint_person_rule %=
+ kwd("name",1) ['=' > parse_string ]
+ / kwd("age" ,1) ['=' > int_]
+ / kwd("size" ,1) ['=' > double_ > 'm']
+ / kwd("favorite color",0,inf) [ '=' > parse_string ]
+ ;
+ //]
+
+ //[reference_keyword_list_constraints
+
+ // Here all the give constraint are resepected : parsing will succeed.
+ test_phrase_parser_attr(
+ "name = \"Hellen\" \n age = 10 \n size = 1.80m \n favorite color = \"blue\" \n favorite color = \"green\" "
+ ,constraint_person_rule
+ ,Hellen);
+ std::cout<<Hellen;
+
+ // Parsing this string will fail because the age and size minimum occurrence requirements aren't met.
+ test_phrase_parser_attr(
+ "name = \"Johny\" \n favorite color = \"blue\" \n favorite color = \"green\" "
+ ,constraint_person_rule
+ ,Johny );
+
+ /*`Parsing the first string will succeed but fail for the second string as the
+ occurrence constraints aren't met. This code should print:[teletype]
+
+ Person : Hellen, 10, 1.8
+ blue
+ green
+ */
+ //]
+ }
+
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/mini_xml2_sr.cpp b/src/boost/libs/spirit/repository/example/qi/mini_xml2_sr.cpp
new file mode 100644
index 00000000..a0d2f3a4
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/mini_xml2_sr.cpp
@@ -0,0 +1,246 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2009 Francois Barel
+
+ 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A mini XML-like parser
+//
+// [ JDG March 25, 2007 ] spirit2
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
+//[mini_xml2_sr_includes
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_subrule.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+//]
+#include <boost/spirit/include/phoenix_fusion.hpp>
+#include <boost/spirit/include/phoenix_stl.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/variant/recursive_variant.hpp>
+#include <boost/foreach.hpp>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+namespace client
+{
+ namespace fusion = boost::fusion;
+ namespace phoenix = boost::phoenix;
+ //[mini_xml2_sr_using
+ namespace qi = boost::spirit::qi;
+ namespace repo = boost::spirit::repository;
+ namespace ascii = boost::spirit::ascii;
+ //]
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Our mini XML tree representation
+ ///////////////////////////////////////////////////////////////////////////
+ struct mini_xml;
+
+ typedef
+ boost::variant<
+ boost::recursive_wrapper<mini_xml>
+ , std::string
+ >
+ mini_xml_node;
+
+ struct mini_xml
+ {
+ std::string name; // tag name
+ std::vector<mini_xml_node> children; // children
+ };
+}
+
+// We need to tell fusion about our mini_xml struct
+// to make it a first-class fusion citizen
+BOOST_FUSION_ADAPT_STRUCT(
+ client::mini_xml,
+ (std::string, name)
+ (std::vector<client::mini_xml_node>, children)
+)
+
+namespace client
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Print out the mini xml tree
+ ///////////////////////////////////////////////////////////////////////////
+ int const tabsize = 4;
+
+ void tab(int indent)
+ {
+ for (int i = 0; i < indent; ++i)
+ std::cout << ' ';
+ }
+
+ struct mini_xml_printer
+ {
+ mini_xml_printer(int indent = 0)
+ : indent(indent)
+ {
+ }
+
+ void operator()(mini_xml const& xml) const;
+
+ int indent;
+ };
+
+ struct mini_xml_node_printer : boost::static_visitor<>
+ {
+ mini_xml_node_printer(int indent = 0)
+ : indent(indent)
+ {
+ }
+
+ void operator()(mini_xml const& xml) const
+ {
+ mini_xml_printer(indent+tabsize)(xml);
+ }
+
+ void operator()(std::string const& text) const
+ {
+ tab(indent+tabsize);
+ std::cout << "text: \"" << text << '"' << std::endl;
+ }
+
+ int indent;
+ };
+
+ void mini_xml_printer::operator()(mini_xml const& xml) const
+ {
+ tab(indent);
+ std::cout << "tag: " << xml.name << std::endl;
+ tab(indent);
+ std::cout << '{' << std::endl;
+
+ BOOST_FOREACH(mini_xml_node const& node, xml.children)
+ {
+ boost::apply_visitor(mini_xml_node_printer(indent), node);
+ }
+
+ tab(indent);
+ std::cout << '}' << std::endl;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Our mini XML grammar definition
+ ///////////////////////////////////////////////////////////////////////////
+ //[mini_xml2_sr_grammar
+ template <typename Iterator>
+ struct mini_xml_grammar
+ : qi::grammar<Iterator, mini_xml(), ascii::space_type>
+ {
+ mini_xml_grammar()
+ : mini_xml_grammar::base_type(entry)
+ {
+ using qi::lit;
+ using qi::lexeme;
+ using ascii::char_;
+ using ascii::string;
+ using namespace qi::labels;
+
+ entry %= (
+ xml %=
+ start_tag[_a = _1]
+ >> *node
+ >> end_tag(_a)
+
+ , node %= xml | text
+
+ , text %= lexeme[+(char_ - '<')]
+
+ , start_tag %=
+ '<'
+ >> !lit('/')
+ >> lexeme[+(char_ - '>')]
+ >> '>'
+
+ , end_tag %=
+ "</"
+ >> lit(_r1)
+ >> '>'
+ );
+ }
+
+ qi::rule<Iterator, mini_xml(), ascii::space_type> entry;
+
+ repo::qi::subrule<0, mini_xml(), qi::locals<std::string> > xml;
+ repo::qi::subrule<1, mini_xml_node()> node;
+ repo::qi::subrule<2, std::string()> text;
+ repo::qi::subrule<3, std::string()> start_tag;
+ repo::qi::subrule<4, void(std::string)> end_tag;
+ };
+ //]
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Main program
+///////////////////////////////////////////////////////////////////////////////
+int main(int argc, char **argv)
+{
+ char const* filename;
+ if (argc > 1)
+ {
+ filename = argv[1];
+ }
+ else
+ {
+ std::cerr << "Error: No input file provided." << std::endl;
+ return 1;
+ }
+
+ std::ifstream in(filename, std::ios_base::in);
+
+ if (!in)
+ {
+ std::cerr << "Error: Could not open input file: "
+ << filename << std::endl;
+ return 1;
+ }
+
+ std::string storage; // We will read the contents here.
+ in.unsetf(std::ios::skipws); // No white space skipping!
+ std::copy(
+ std::istream_iterator<char>(in),
+ std::istream_iterator<char>(),
+ std::back_inserter(storage));
+
+ typedef client::mini_xml_grammar<std::string::const_iterator> mini_xml_grammar;
+ mini_xml_grammar xml; // Our grammar
+ client::mini_xml ast; // Our tree
+
+ using boost::spirit::ascii::space;
+ std::string::const_iterator iter = storage.begin();
+ std::string::const_iterator end = storage.end();
+ bool r = phrase_parse(iter, end, xml, space, ast);
+
+ if (r && iter == end)
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing succeeded\n";
+ std::cout << "-------------------------\n";
+ client::mini_xml_printer printer;
+ printer(ast);
+ return 0;
+ }
+ else
+ {
+ std::string::const_iterator some = iter + std::min(30, int(end - iter));
+ std::string context(iter, (some>end)?end:some);
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing failed\n";
+ std::cout << "stopped at: \"" << context << "...\"\n";
+ std::cout << "-------------------------\n";
+ return 1;
+ }
+}
+
+
diff --git a/src/boost/libs/spirit/repository/example/qi/options.cpp b/src/boost/libs/spirit/repository/example/qi/options.cpp
new file mode 100644
index 00000000..3bad27c2
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/options.cpp
@@ -0,0 +1,122 @@
+/*=============================================================================
+ Copyright (c) 2001-2011 Joel de Guzman
+ 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)
+=============================================================================*/
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/karma.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <boost/spirit/repository/include/qi_kwd.hpp>
+#include <boost/spirit/repository/include/qi_keywords.hpp>
+#include <boost/optional.hpp>
+#include <boost/cstdint.hpp>
+#include <iostream>
+#include <string>
+#include <cstdlib>
+#include <iterator>
+#include <map>
+#include <vector>
+
+// Data structure definitions
+
+// preprocessor constants
+typedef std::pair<std::string, boost::int32_t> preprocessor_symbol;
+
+BOOST_FUSION_ADAPT_STRUCT( preprocessor_symbol,
+ (std::string, first)
+ (boost::int32_t, second)
+)
+
+// A data structure to store our program options
+struct program_options {
+ std::vector<std::string> includes; // include paths
+ typedef std::vector< preprocessor_symbol > preprocessor_symbols_container; // symbol container type definition
+ preprocessor_symbols_container preprocessor_symbols; // preprocessor symbols
+ boost::optional<std::string> output_filename; // output file name
+ std::string source_filename; // source file name
+
+};
+
+// Make the program_options compatible with fusion sequences
+BOOST_FUSION_ADAPT_STRUCT( program_options,
+ (std::vector<std::string>, includes)
+ (program_options::preprocessor_symbols_container, preprocessor_symbols)
+ (boost::optional<std::string>, output_filename)
+ (std::string, source_filename)
+)
+
+
+// Output helper to check that the data parsed matches what we expect
+std::ostream &operator<<(std::ostream &os, const program_options &obj)
+{
+ using boost::spirit::karma::string;
+ using boost::spirit::karma::int_;
+ using boost::spirit::karma::lit;
+ using boost::spirit::karma::buffer;
+ using boost::spirit::karma::eol;
+ using boost::spirit::karma::format;
+ return os<<format(
+ lit("Includes:") << (string % ',') << eol
+ << lit("Preprocessor symbols:") << ((string <<"="<< int_) % ',') << eol
+ << buffer[-( lit("Output file:")<< string << eol)]
+ << lit("Source file:")<< string << eol
+ ,obj);
+ return os;
+}
+
+
+int
+main()
+{
+
+ {
+ // Pull everything we need from qi into this scope
+ using boost::spirit::repository::qi::kwd;
+ using boost::spirit::qi::inf;
+ using boost::spirit::ascii::space_type;
+ using boost::spirit::ascii::alnum;
+ using boost::spirit::qi::int_;
+ using boost::spirit::qi::rule;
+ using boost::spirit::qi::lit;
+ using boost::spirit::qi::attr;
+ using boost::spirit::qi::lexeme;
+ using boost::spirit::qi::hold;
+ using boost::spirit::qi::ascii::space;
+
+ //Rule declarations
+ rule<const char *, std::string(), space_type> parse_string;
+ rule<const char *, program_options(), space_type> kwd_rule;
+
+ // A string parser
+ parse_string %= lexeme[*alnum];
+
+ namespace phx=boost::phoenix;
+ // kwd rule
+ kwd_rule %=
+ kwd("--include")[ parse_string ]
+ / kwd("--define")[ parse_string >> ((lit('=') > int_) | attr(1)) ]
+ / kwd("--output",0,1)[ parse_string ]
+ / hold [kwd("--source",1)[ parse_string ]]
+ ;
+ //
+
+ using boost::spirit::qi::phrase_parse;
+
+ // Let's check what that parser can do
+ program_options result;
+
+ char const input[]="--include path1 --source file1 --define SYMBOL1=10 --include path2 --source file2";
+ char const* f(input);
+ char const* l(f + strlen(f));
+ if (phrase_parse(f, l, kwd_rule, space,result) && (f == l))
+ std::cout << "ok" << std::endl;
+ else
+ std::cout << "fail" << std::endl;
+
+ // Output the result to the console
+ std::cout<<result<<std::endl;
+}
+ return 0;
+}
diff --git a/src/boost/libs/spirit/repository/example/qi/seek.cpp b/src/boost/libs/spirit/repository/example/qi/seek.cpp
new file mode 100644
index 00000000..c33bc1f3
--- /dev/null
+++ b/src/boost/libs/spirit/repository/example/qi/seek.cpp
@@ -0,0 +1,48 @@
+/*//////////////////////////////////////////////////////////////////////////////
+ Copyright (c) 2011 Jamboree
+
+ 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)
+//////////////////////////////////////////////////////////////////////////////*/
+
+// [ Jamboree Oct 27, 2011 ] new example.
+
+
+#include <cstdlib>
+#include <iostream>
+
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/repository/include/qi_seek.hpp>
+
+
+int main()
+{
+ //[reference_qi_seek_namespace
+ namespace qi = boost::spirit::qi;
+ namespace repo = boost::spirit::repository;
+ //]
+
+ typedef std::string::const_iterator iterator;
+
+ //[reference_qi_seek_vars
+ std::string str("/*C-style comment*/");
+ iterator it = str.begin();
+ iterator end = str.end();
+ //]
+
+ //[reference_qi_seek_parse
+ if (qi::parse(it, end, "/*" >> repo::qi::seek["*/"]))
+ {
+ std::cout << "-------------------------------- \n";
+ std::cout << "Parsing succeeded.\n";
+ std::cout << "---------------------------------\n";
+ }
+ else
+ {
+ std::cout << "-------------------------------- \n";
+ std::cout << "Unterminated /* comment.\n";
+ std::cout << "-------------------------------- \n";
+ }//]
+
+ return EXIT_SUCCESS;
+}