mirror of
https://github.com/boostorg/spirit.git
synced 2026-01-19 04:42:11 +00:00
It is better to manage warnings on our side to know what warnings we need to fix or suppress, and the only thing that header does is disabling deprecation warnings on MSVC and ICC which we would prefer to not show to users.
125 lines
4.8 KiB
C++
125 lines
4.8 KiB
C++
/*=============================================================================
|
|
Copyright (c) 2001-2010 Hartmut Kaiser
|
|
Copyright (c) 2001-2010 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/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>, qi::domain>
|
|
{
|
|
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 of the rule.
|
|
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 (referenced
|
|
// by the first argument) with the values taken from the parsing
|
|
// results (referenced by the second argument).
|
|
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));
|
|
}
|
|
|
|
// The function fail() is called whenever the parsing of the right hand
|
|
// side of the rule fails. We don't need to do anything here.
|
|
static void fail(boost::gregorian::date&) {}
|
|
};
|
|
}}}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
namespace client
|
|
{
|
|
namespace qi = boost::spirit::qi;
|
|
|
|
template <typename Iterator>
|
|
bool parse_date(Iterator& first, Iterator last, boost::gregorian::date& d)
|
|
{
|
|
typedef boost::fusion::vector<int, int, int> date_parts;
|
|
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;
|
|
}
|
|
|
|
|