$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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;
+}