Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r56595 - trunk/libs/spirit/example/qi
From: hartmut.kaiser_at_[hidden]
Date: 2009-10-05 10:32:55


Author: hkaiser
Date: 2009-10-05 10:32:54 EDT (Mon, 05 Oct 2009)
New Revision: 56595
URL: http://svn.boost.org/trac/boost/changeset/56595

Log:
Spirit: added example demonstrating transform_attribute
Added:
   trunk/libs/spirit/example/qi/parse_date.cpp (contents, props changed)
Text files modified:
   trunk/libs/spirit/example/qi/CMakeLists.txt | 1 +
   trunk/libs/spirit/example/qi/Jamfile | 1 +
   2 files changed, 2 insertions(+), 0 deletions(-)

Modified: trunk/libs/spirit/example/qi/CMakeLists.txt
==============================================================================
--- trunk/libs/spirit/example/qi/CMakeLists.txt (original)
+++ trunk/libs/spirit/example/qi/CMakeLists.txt 2009-10-05 10:32:54 EDT (Mon, 05 Oct 2009)
@@ -23,6 +23,7 @@
 boost_add_executable( num_list3 num_list3.cpp )
 boost_add_executable( num_list4 num_list4.cpp )
 boost_add_executable( reorder_struct reorder_struct.cpp )
+boost_add_executable( parse_date parse_date.cpp )
 
 boost_add_executable( calc1 calc1.cpp )
 boost_add_executable( calc2 calc2.cpp )

Modified: trunk/libs/spirit/example/qi/Jamfile
==============================================================================
--- trunk/libs/spirit/example/qi/Jamfile (original)
+++ trunk/libs/spirit/example/qi/Jamfile 2009-10-05 10:32:54 EDT (Mon, 05 Oct 2009)
@@ -24,6 +24,7 @@
 exe num_list3 : num_list3.cpp ;
 exe num_list4 : num_list4.cpp ;
 exe reorder_struct : reorder_struct.cpp ;
+exe parse_date : parse_date.cpp ;
 
 exe calculator1 : calc1.cpp ;
 exe calculator2 : calc2.cpp ;

Added: trunk/libs/spirit/example/qi/parse_date.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/parse_date.cpp 2009-10-05 10:32:54 EDT (Mon, 05 Oct 2009)
@@ -0,0 +1,123 @@
+/*=============================================================================
+ Copyright (c) 2001-2009 Hartmut Kaiser
+ Copyright (c) 2001-2009 Joel de Guzman
+
+ 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)
+=============================================================================*/
+
+// This example is not meant to be a sophisticated date parser. It's sole
+// purpose is to demonstrate the intrinsic attribute transformation
+// capabilities of a rule.
+//
+// Note how the rule exposes a fusion sequence, but gets passed an instance of
+// a boost::gregorian::date as the attribute. In order to make these types
+// compatible for the rule we define a specialization of the customization
+// point called 'transform_attribute'.
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/date_time.hpp>
+
+// define custom transformation
+namespace boost { namespace spirit { namespace traits
+{
+ // This specialization of the customization point transform_attribute
+ // allows to pass a boost::gregorian::date to a rule which is expecting
+ // a fusion sequence consisting out of three integers as its attribute.
+ template<>
+ struct transform_attribute<
+ boost::gregorian::date, fusion::vector<int, int, int> >
+ {
+ typedef fusion::vector<int, int, int> date_parts;
+
+ // The embedded typedef 'type' exposes the attribute as it will be
+ // passed to the right hand side.
+ typedef date_parts type;
+
+ // The function pre() is called for down-stream conversion of the
+ // attribute supplied to the rule to the attribute expected by the
+ // right hand side.
+ // The supplied attribute might have been pre-initialized by parsers
+ // (i.e. semantic actions) higher up the parser hierarchy (in the
+ // grammar, in which case we would need to properly initialize the
+ // returned value from the argument. In this example this is not
+ // required, so we just create a new instance of a date_parts.
+ static date_parts pre(boost::gregorian::date)
+ {
+ return date_parts();
+ }
+
+ // The function post() is called for up-stream conversion of the
+ // results returned from parsing the right hand side of the rule.
+ // We need to initialize the attribute supplied to the rule with the
+ // values taken from the parsing results.
+ static void post(boost::gregorian::date& d, date_parts const& v)
+ {
+ d = boost::gregorian::date(fusion::at_c<0>(v), fusion::at_c<1>(v)
+ , fusion::at_c<2>(v));
+ }
+ };
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace client
+{
+ namespace qi = boost::spirit::qi;
+ namespace fusion = boost::fusion;
+
+ typedef fusion::vector<int, int, int> date_parts;
+
+ template <typename Iterator>
+ bool parse_date(Iterator& first, Iterator last, boost::gregorian::date& d)
+ {
+ qi::rule<Iterator, date_parts(), qi::space_type> date =
+ qi::int_ >> '-' >> qi::int_ >> '-' >> qi::int_;
+
+ return phrase_parse(first, last, date, qi::space, d);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+int main()
+{
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+ std::cout << "\t\tA date parser for Spirit...\n\n";
+ std::cout << "/////////////////////////////////////////////////////////\n\n";
+
+ std::cout << "Give me a date of the form : year-month-day\n";
+ std::cout << "Type [q or Q] to quit\n\n";
+
+ std::string str;
+ while (getline(std::cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ boost::gregorian::date d;
+ std::string::const_iterator iter = str.begin();
+ std::string::const_iterator end = str.end();
+ bool r = client::parse_date(iter, end, d);
+
+ if (r && iter == end)
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing succeeded\n";
+ std::cout << "got: " << d << std::endl;
+ std::cout << "\n-------------------------\n";
+ }
+ else
+ {
+ std::cout << "-------------------------\n";
+ std::cout << "Parsing failed\n";
+ std::cout << "-------------------------\n";
+ }
+ }
+
+ std::cout << "Bye... :-) \n\n";
+ return 0;
+ 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