Encapsulate parser's roots. Leave only interface.

This commit is contained in:
Sergey Magidovich 2015-10-23 22:11:07 +03:00
parent ef798ab744
commit 7113c03c7f
7 changed files with 114 additions and 79 deletions

View file

@ -13,7 +13,8 @@ ROOT_DIR = ../..
include($$ROOT_DIR/common.pri)
SOURCES += osm_time_range.cpp
SOURCES += osm_time_range.cpp parse.cpp
HEADERS += osm_time_range.hpp \
osm_parsers.hpp \
osm_parsers_terminals.hpp \
parse.hpp \

View file

@ -13,5 +13,4 @@ INCLUDEPATH += $$OPENING_HOURS_INCLUDE
SOURCES += osm_time_range_tests.cpp
HEADERS += $$OPENING_HOURS_INCLUDE/osm_time_range.hpp \
$$OPENING_HOURS_INCLUDE/osm_parsers.hpp
$$OPENING_HOURS_INCLUDE/osm_parsers_terminals.hpp
$$OPENING_HOURS_INCLUDE/parse.hpp \

View file

@ -23,7 +23,7 @@
*/
#include "osm_time_range.hpp"
#include "osm_parsers.hpp"
#include "parse.hpp"
#include <iostream>
#include <sstream>
@ -57,31 +57,13 @@ bool test(Char const * in, Parser const & p, bool full_match = true)
return boost::spirit::qi::parse(in, last, p) && (!full_match || (in == last));
}
template <template <typename> class Parser, typename ParseResult, typename Char>
template <typename ParseResult, typename Char>
std::basic_string<Char> ParseAndUnparse(Char const * input)
{
// we don't care about the result of the "what" function.
// we only care that all parsers have it:
using boost::spirit::qi::phrase_parse;
using boost::spirit::standard_wide::space;
ParseResult parseResult;
std::basic_string<Char> const str(input);
Parser<decltype(begin(str))> p;
boost::spirit::qi::what(p);
auto first = begin(str);
auto const last = end(str);
auto parsed = boost::spirit::qi::phrase_parse(
first,
last,
p,
space,
parseResult);
if (!parsed || first != last)
ParseResult parseResult;
if (!osmoh::Parse(str, parseResult))
return ":CAN'T PARSE:";
std::basic_stringstream<Char> sstr;
@ -408,69 +390,57 @@ BOOST_AUTO_TEST_CASE(OpeningHoursTimerange_TestParseUnparse)
{
{
auto const rule = "06:00";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "06:00+";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "06:00-02:00";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "06:00-02:00+";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "06:00-02:00/03";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "06:00-02:00/21:03";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "dusk";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
}
{
auto const rule = "dawn+";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
}
{
auto const rule = "sunrise-sunset";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
}
{
auto const rule = "(dusk-12:12)";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
}
{
auto const rule = "(dusk-12:12)+";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
}
{
auto const rule = "(dusk-12:12)-sunset";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::time_selector,
osmoh::TTimespans>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TTimespans>(rule);
}
}
@ -478,50 +448,42 @@ BOOST_AUTO_TEST_CASE(OpeningHoursWeekdays_TestParseUnparse)
{
{
auto const rule = "SH -2 days";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::weekday_selector,
osmoh::Weekdays>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::Weekdays>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "SH +2 days";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::weekday_selector,
osmoh::Weekdays>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::Weekdays>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "SH +1 day";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::weekday_selector,
osmoh::Weekdays>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::Weekdays>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "PH";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::weekday_selector,
osmoh::Weekdays>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::Weekdays>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "SH";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::weekday_selector,
osmoh::Weekdays>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::Weekdays>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "Mo,We,Th,Fr";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::weekday_selector,
osmoh::Weekdays>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::Weekdays>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "Fr-Sa";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::weekday_selector,
osmoh::Weekdays>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::Weekdays>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "PH,Sa,Su";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::weekday_selector,
osmoh::Weekdays>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::Weekdays>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
}
@ -530,26 +492,22 @@ BOOST_AUTO_TEST_CASE(OpeningHoursMonthdayRanges_TestParseUnparse)
{
{
auto const rule = "Jan";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::month_selector,
osmoh::TMonthdayRanges>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TMonthdayRanges>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "Mar 10+";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::month_selector,
osmoh::TMonthdayRanges>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TMonthdayRanges>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "Jan-Feb";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::month_selector,
osmoh::TMonthdayRanges>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TMonthdayRanges>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
{
auto const rule = "Jan-Feb/10";
auto const parsedUnparsed = ParseAndUnparse<osmoh::parsing::month_selector,
osmoh::TMonthdayRanges>(rule);
auto const parsedUnparsed = ParseAndUnparse<osmoh::TMonthdayRanges>(rule);
BOOST_CHECK_EQUAL(parsedUnparsed, rule);
}
}

View file

@ -1,5 +1,7 @@
#pragma once
#include "osm_time_range.hpp"
// #define BOOST_SPIRIT_DEBUG 1
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
@ -22,7 +24,6 @@
#include <boost/date_time/gregorian/gregorian.hpp>
#endif
#include "osm_time_range.hpp"
#include "osm_parsers_terminals.hpp"
namespace osmoh

View file

@ -1,8 +1,3 @@
#pragma once
#include "osm_time_range.hpp"
#include <boost/spirit/include/qi.hpp>
namespace osmoh
{
namespace parsing

View file

@ -0,0 +1,70 @@
#include "parse.hpp"
#include "osm_parsers.hpp"
namespace
{
template <typename Context, typename Iterator>
struct context_parser;
template<typename Iterator> struct context_parser<osmoh::TTimespans, Iterator>
{
using type = osmoh::parsing::time_selector<Iterator>;
};
template<typename Iterator> struct context_parser<osmoh::Weekdays, Iterator>
{
using type = osmoh::parsing::weekday_selector<Iterator>;
};
template<typename Iterator> struct context_parser<osmoh::TMonthdayRanges, Iterator>
{
using type = osmoh::parsing::month_selector<Iterator>;
};
template <typename Context, typename Iterator>
using context_parser_t = typename context_parser<Context, Iterator>::type;
template <typename Context>
bool ParseImp(std::string const & str, Context & context)
{
using boost::spirit::qi::phrase_parse;
using boost::spirit::standard_wide::space;
context_parser_t<Context, decltype(begin(str))> parser;
#ifndef NDEBUG
boost::spirit::qi::what(parser);
#endif
auto first = begin(str);
auto const last = end(str);
auto parsed = phrase_parse(
first,
last,
parser,
space,
context);
if (!parsed || first != last)
return false;
return true;
}
} // namespace
namespace osmoh
{
bool Parse(std::string const & str, osmoh::TTimespans & s)
{
return ParseImp(str, s);
}
bool Parse(std::string const & str, osmoh::Weekdays & w)
{
return ParseImp(str, w);
}
bool Parse(std::string const & str, osmoh::TMonthdayRanges & m)
{
return ParseImp(str, m);
}
} // namespace osmoh

View file

@ -0,0 +1,11 @@
#pragma once
#include "osm_time_range.hpp"
#include <string>
namespace osmoh
{
bool Parse(std::string const &, TTimespans &);
bool Parse(std::string const &, Weekdays &);
bool Parse(std::string const &, TMonthdayRanges &);
} // namespace osmoh