Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r70212 - trunk/libs/spirit/repository/example/qi
From: joel_at_[hidden]
Date: 2011-03-19 20:01:57


Author: djowel
Date: 2011-03-19 20:01:57 EDT (Sat, 19 Mar 2011)
New Revision: 70212
URL: http://svn.boost.org/trac/boost/changeset/70212

Log:
patch from teejay
Added:
   trunk/libs/spirit/repository/example/qi/derived.cpp (contents, props changed)
   trunk/libs/spirit/repository/example/qi/options.cpp (contents, props changed)
Text files modified:
   trunk/libs/spirit/repository/example/qi/Jamfile | 2 ++
   1 files changed, 2 insertions(+), 0 deletions(-)

Modified: trunk/libs/spirit/repository/example/qi/Jamfile
==============================================================================
--- trunk/libs/spirit/repository/example/qi/Jamfile (original)
+++ trunk/libs/spirit/repository/example/qi/Jamfile 2011-03-19 20:01:57 EDT (Sat, 19 Mar 2011)
@@ -19,3 +19,5 @@
 exe mini_xml2_sr : mini_xml2_sr.cpp ;
 exe advance : advance.cpp ;
 exe keywords : keywords.cpp ;
+exe derived : derived.cpp ;
+exe options : options.cpp ;

Added: trunk/libs/spirit/repository/example/qi/derived.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/example/qi/derived.cpp 2011-03-19 20:01:57 EDT (Sat, 19 Mar 2011)
@@ -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;
+}

Added: trunk/libs/spirit/repository/example/qi/options.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/repository/example/qi/options.cpp 2011-03-19 20:01:57 EDT (Sat, 19 Mar 2011)
@@ -0,0 +1,121 @@
+/*=============================================================================
+ 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 <iostream>
+#include <string>
+#include <cstdlib>
+#include <iterator>
+#include <map>
+#include <vector>
+
+// Data structure definitions
+
+// preprocessor constants
+typedef std::pair<std::string, int32_t> preprocessor_symbol;
+
+BOOST_FUSION_ADAPT_STRUCT( preprocessor_symbol,
+ (std::string, first)
+ (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;
+}


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