2
0
mirror of https://github.com/boostorg/spirit.git synced 2026-01-19 04:42:11 +00:00
Files
spirit/example/qi/parse_date.cpp
Nikita Kniazev f44479bcd3 Remove boost/config/warning_disable.hpp usage
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.
2021-08-24 03:14:12 +03:00

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;
}