forked from organicmaps/organicmaps-tmp
Refactoring.
This commit is contained in:
parent
11f242465b
commit
b8970aa481
7 changed files with 736 additions and 680 deletions
45
3party/opening_hours/adapted_structs.hpp
Normal file
45
3party/opening_hours/adapted_structs.hpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "osm_time_range.hpp"
|
||||
|
||||
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
|
||||
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::Time,
|
||||
(uint8_t, hours)
|
||||
(uint8_t, minutes)
|
||||
(uint8_t, flags)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::TimeSpan,
|
||||
(osmoh::Time, from)
|
||||
(osmoh::Time, to)
|
||||
(uint8_t, flags)
|
||||
(osmoh::Time, period)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::Weekday,
|
||||
(uint8_t, weekdays)
|
||||
(uint16_t, nth)
|
||||
(int32_t, offset)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::State,
|
||||
(uint8_t, state)
|
||||
(std::string, comment)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::TimeRule,
|
||||
(osmoh::TWeekdays, weekdays)
|
||||
(osmoh::TTimeSpans, timespan)
|
||||
(osmoh::State, state)
|
||||
(uint8_t, int_flags)
|
||||
)
|
|
@ -14,4 +14,6 @@ ROOT_DIR = ../..
|
|||
include($$ROOT_DIR/common.pri)
|
||||
|
||||
SOURCES += osm_time_range.cpp
|
||||
HEADERS += osm_time_range.hpp
|
||||
HEADERS += osm_time_range.hpp \
|
||||
osm_parsers.hpp \
|
||||
adapted_structs.hpp
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
TARGET = opening_hours_tests
|
||||
CONFIG += console worn_off
|
||||
CONFIG -= app_bundle
|
||||
|
@ -9,7 +8,10 @@ DEPENDENCIES += opening_hours \
|
|||
|
||||
include($$ROOT_DIR/common.pri)
|
||||
|
||||
INCLUDEPATH += $$ROOT_DIR/3party/opening_hours
|
||||
OPENING_HOURS_INCLUDE = $$ROOT_DIR/3party/opening_hours
|
||||
INCLUDEPATH += $$OPENING_HOURS_INCLUDE
|
||||
|
||||
SOURCES += osm_time_range_tests.cpp
|
||||
SOURCES += ../osm_time_range.hpp
|
||||
HEADERS += $$OPENING_HOURS_INCLUDE/osm_time_range.hpp \
|
||||
$$OPENING_HOURS_INCLUDE/osm_parsers.hpp
|
||||
$$OPENING_HOURS_INCLUDE/adopted_structs.hpp
|
||||
|
|
|
@ -21,9 +21,11 @@
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include "osm_time_range.hpp"
|
||||
#include <osm_time_range.hpp>
|
||||
#include <osm_parsers.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <locale>
|
||||
|
@ -54,6 +56,41 @@ 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 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;
|
||||
|
||||
// TODO move to template
|
||||
osmoh::TTimeRules timeRules;
|
||||
std::basic_string<Char> const str(input);
|
||||
|
||||
Parser<decltype(begin(str))> p;
|
||||
boost::spirit::qi::what(p);
|
||||
|
||||
auto parsed = boost::spirit::qi::phrase_parse(
|
||||
begin(str),
|
||||
end(str),
|
||||
p,
|
||||
space,
|
||||
timeRules);
|
||||
|
||||
if (!parsed)
|
||||
return {};
|
||||
|
||||
std::basic_stringstream<Char> sstr;
|
||||
for (auto it = begin(timeRules); it != end(timeRules); ++it)
|
||||
{
|
||||
sstr << (*it);
|
||||
if (next(it) != end(timeRules))
|
||||
sstr << ' ';
|
||||
}
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(OpeningHours_Locale)
|
||||
{
|
||||
|
@ -199,13 +236,15 @@ BOOST_AUTO_TEST_CASE(OpeningHours_StaticSet)
|
|||
{
|
||||
{
|
||||
// TODO(mgsergio) move validation from parsing
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("06:00-02:00/21:03");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
// OSMTimeRange oh = OSMTimeRange::FromString("06:00-02:00/21:03");
|
||||
// BOOST_CHECK(oh.IsValid());
|
||||
auto const rule = "06:00-02:00/21:03";
|
||||
BOOST_CHECK_EQUAL(ParseAndUnparse<osmoh::parsing::time_domain>(rule), rule);
|
||||
}
|
||||
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("06:00-09:00/03");
|
||||
BOOST_CHECK(oh.IsValid());
|
||||
// BOOST_CHECK(test_hard<osmoh::parsing::time_domain>("06:00-09:00/03"));
|
||||
//BOOST_CHECK(oh.IsValid());
|
||||
}
|
||||
{
|
||||
OSMTimeRange oh = OSMTimeRange::FromString("06:00-07:00/03");
|
||||
|
|
618
3party/opening_hours/osm_parsers.hpp
Normal file
618
3party/opening_hours/osm_parsers.hpp
Normal file
|
@ -0,0 +1,618 @@
|
|||
#pragma once
|
||||
|
||||
#include "adapted_structs.hpp"
|
||||
|
||||
//#define BOOST_SPIRIT_DEBUG 1
|
||||
#define BOOST_SPIRIT_USE_PHOENIX_V3
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/repository/include/qi_subrule.hpp>
|
||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
||||
#include <boost/spirit/include/phoenix_fusion.hpp>
|
||||
#include <boost/spirit/include/phoenix_stl.hpp>
|
||||
#include <boost/spirit/include/phoenix_statement.hpp>
|
||||
#include <boost/spirit/include/phoenix_bind.hpp>
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/date_time/gregorian/gregorian.hpp>
|
||||
#pragma clang diagnostic pop
|
||||
#else
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/date_time/gregorian/gregorian.hpp>
|
||||
#endif
|
||||
|
||||
namespace osmoh
|
||||
{
|
||||
namespace phx = boost::phoenix;
|
||||
|
||||
class test_impl
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
struct result { typedef void type; };
|
||||
|
||||
template <typename Arg>
|
||||
void operator() (const Arg & a) const
|
||||
{
|
||||
std::cout << a << " \t(" << typeid(a).name() << ")" << std::endl;
|
||||
}
|
||||
};
|
||||
phx::function<test_impl> const test = test_impl();
|
||||
|
||||
inline boost::posix_time::time_period make_time_period(boost::gregorian::date const & d,
|
||||
osmoh::TimeSpan const & ts)
|
||||
{
|
||||
using boost::posix_time::ptime;
|
||||
using boost::posix_time::hours;
|
||||
using boost::posix_time::minutes;
|
||||
using boost::posix_time::time_period;
|
||||
|
||||
/// TODO(yershov@): Need create code for calculate real values
|
||||
ptime sunrise(d, hours(6));
|
||||
ptime sunset(d, hours(19));
|
||||
|
||||
ptime t1, t2;
|
||||
|
||||
if (ts.from.flags & osmoh::Time::eSunrise)
|
||||
t1 = sunrise;
|
||||
else if (ts.from.flags & osmoh::Time::eSunset)
|
||||
t1 = sunset;
|
||||
else
|
||||
t1 = ptime(d, hours((ts.from.flags & osmoh::Time::eHours) ? ts.from.hours : 0) + minutes((ts.from.flags & osmoh::Time::eMinutes) ? ts.from.minutes : 0));
|
||||
|
||||
t2 = t1;
|
||||
|
||||
if (ts.to.flags & osmoh::Time::eSunrise)
|
||||
t2 = sunrise;
|
||||
else if (ts.to.flags & osmoh::Time::eSunset)
|
||||
t2 = sunset;
|
||||
else
|
||||
{
|
||||
t2 = ptime(d, hours((ts.to.flags & osmoh::Time::eHours) ? ts.to.hours : 24) + minutes((ts.to.flags & osmoh::Time::eMinutes) ? ts.to.minutes : 0));
|
||||
if (t2 < t1)
|
||||
t2 += hours(24);
|
||||
}
|
||||
|
||||
return time_period(t1, t2);
|
||||
}
|
||||
|
||||
namespace parsing
|
||||
{
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace repo = boost::spirit::repository;
|
||||
|
||||
namespace charset = boost::spirit::standard_wide;
|
||||
using space_type = charset::space_type;
|
||||
|
||||
class dash_ : public qi::symbols<wchar_t>
|
||||
{
|
||||
public:
|
||||
dash_()
|
||||
{
|
||||
add
|
||||
(L"-")
|
||||
/* not standard */
|
||||
(L"–")(L"—")(L"-")(L"~")(L"~")(L"〜")(L"to")(L"às")(L"ás")(L"as")(L"a")(L"ate")(L"bis")
|
||||
;
|
||||
}
|
||||
} dash;
|
||||
|
||||
class event_ : public qi::symbols<wchar_t, uint8_t>
|
||||
{
|
||||
public:
|
||||
event_()
|
||||
{
|
||||
add
|
||||
(L"dawn", osmoh::Time::eSunrise)(L"sunrise", osmoh::Time::eSunrise)(L"sunset", osmoh::Time::eSunset)(L"dusk", osmoh::Time::eSunset)
|
||||
;
|
||||
}
|
||||
} event;
|
||||
|
||||
struct wdays_ : qi::symbols<wchar_t, unsigned>
|
||||
{
|
||||
wdays_()
|
||||
{
|
||||
add
|
||||
(L"mo", 0)(L"tu", 1)(L"we", 2)(L"th", 3)(L"fr", 4)(L"sa", 5)(L"su", 6) // en
|
||||
(L"mon", 0)(L"tue", 1)(L"wed", 2)(L"thu", 3)(L"fri", 4)(L"sat", 5)(L"sun", 6) // en
|
||||
(L"пн", 0)(L"вт", 1)(L"ср", 2)(L"чт", 3)(L"пт", 4)(L"сб", 5)(L"вс", 6) // ru
|
||||
(L"пн.", 0)(L"вт.", 1)(L"ср.", 2)(L"чт.", 3)(L"пт.", 4)(L"сб.", 5)(L"вс.", 6) // ru
|
||||
(L"lu", 0)(L"ma", 1)(L"me", 2)(L"je", 3)(L"ve", 4)(L"sa", 5)(L"di", 6) // fr
|
||||
(L"lu", 0)(L"ma", 1)(L"me", 2)(L"gi", 3)(L"ve", 4)(L"sa", 5)(L"do", 6) // it
|
||||
(L"lu", 0)(L"ma", 1)(L"mi", 2)(L"ju", 3)(L"vie", 4)(L"sá", 5)(L"do", 6) // sp
|
||||
(L"週一", 0)(L"週二", 1)(L"週三", 2)(L"週四", 3)(L"週五", 4)(L"週六", 5)(L"週日", 6) // ch traditional
|
||||
(L"senin", 0)(L"selasa", 1)(L"rabu", 2)(L"kamis", 3)(L"jum'at", 4)(L"sabtu", 5)(L"minggu", 6) // indonesian
|
||||
|
||||
(L"wd", 2)
|
||||
|
||||
;
|
||||
}
|
||||
} wdays;
|
||||
|
||||
struct month_ : qi::symbols<wchar_t, unsigned>
|
||||
{
|
||||
month_()
|
||||
{
|
||||
add
|
||||
(L"jan", 1)(L"feb", 2)(L"mar", 3)(L"apr", 4)(L"may", 5)(L"jun", 6)
|
||||
(L"jul", 7)(L"aug", 8)(L"sep", 9)(L"oct", 10)(L"nov", 11)(L"dec", 12)
|
||||
;
|
||||
}
|
||||
} month;
|
||||
|
||||
struct hours_ : qi::symbols<char, uint8_t>
|
||||
{
|
||||
hours_()
|
||||
{
|
||||
add
|
||||
( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)
|
||||
;
|
||||
}
|
||||
} hours;
|
||||
|
||||
struct exthours_ : qi::symbols<char, uint8_t>
|
||||
{
|
||||
exthours_()
|
||||
{
|
||||
add
|
||||
( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39)
|
||||
("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)
|
||||
;
|
||||
}
|
||||
} exthours;
|
||||
|
||||
struct minutes_ : qi::symbols<char, uint8_t>
|
||||
{
|
||||
minutes_()
|
||||
{
|
||||
add
|
||||
( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39)
|
||||
("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)("49", 49)
|
||||
("50", 50)("51", 51)("52", 52)("53", 53)("54", 54)("55", 55)("56", 56)("57", 57)("58", 58)("59", 59)
|
||||
;
|
||||
}
|
||||
} minutes;
|
||||
|
||||
struct weeknum_ : qi::symbols<char, unsigned>
|
||||
{
|
||||
weeknum_()
|
||||
{
|
||||
add
|
||||
( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9)
|
||||
("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39)
|
||||
("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)("49", 49)
|
||||
("50", 50)("51", 51)("52", 52)("53", 53)
|
||||
;
|
||||
}
|
||||
} weeknum;
|
||||
|
||||
struct daynum_ : qi::symbols<char, unsigned>
|
||||
{
|
||||
daynum_()
|
||||
{
|
||||
add
|
||||
("1", 1)("2", 2)("3", 3)("4", 4)("5", 5)("6", 6)("7", 7)("8", 8)("9", 9)
|
||||
("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
("30", 30)("31", 31)
|
||||
;
|
||||
}
|
||||
} daynum;
|
||||
|
||||
template <class Iterator>
|
||||
class year_selector : public qi::grammar<Iterator, space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, space_type> year;
|
||||
qi::rule<Iterator, space_type> year_range;
|
||||
qi::rule<Iterator, space_type> main;
|
||||
public:
|
||||
year_selector() : year_selector::base_type(main)
|
||||
{
|
||||
using qi::uint_;
|
||||
using qi::lit;
|
||||
using charset::char_;
|
||||
|
||||
static const qi::int_parser<unsigned, 10, 4, 4> _4digit = {};
|
||||
|
||||
year %= _4digit;
|
||||
year_range %= (year >> dash >> year >> '/' >> uint_)
|
||||
| (year >> dash >> year)
|
||||
| year >> char_('+')
|
||||
| year
|
||||
;
|
||||
main %= year_range % ',';
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class week_selector : public qi::grammar<Iterator, space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, space_type> week;
|
||||
qi::rule<Iterator, space_type> year_range;
|
||||
qi::rule<Iterator, space_type> main;
|
||||
public:
|
||||
week_selector() : week_selector::base_type(main)
|
||||
{
|
||||
using qi::uint_;
|
||||
using qi::lit;
|
||||
using charset::char_;
|
||||
|
||||
week %= (weeknum >> dash >> weeknum >> '/' >> uint_)
|
||||
| (weeknum >> dash >> weeknum)
|
||||
| weeknum
|
||||
;
|
||||
|
||||
main %= charset::no_case[lit("week")] >> week % ',';
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class month_selector : public qi::grammar<Iterator, space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, space_type> date;
|
||||
qi::rule<Iterator, space_type> day_offset;
|
||||
qi::rule<Iterator, space_type> date_with_offsets;
|
||||
qi::rule<Iterator, space_type> monthday_range;
|
||||
qi::rule<Iterator, space_type> month_range;
|
||||
qi::rule<Iterator, space_type> main;
|
||||
public:
|
||||
month_selector() : month_selector::base_type(main)
|
||||
{
|
||||
using qi::int_;
|
||||
using qi::lit;
|
||||
using qi::double_;
|
||||
using qi::lexeme;
|
||||
using charset::char_;
|
||||
|
||||
static const qi::int_parser<unsigned, 10, 4, 4> year = {};
|
||||
|
||||
day_offset %= (char_('+') | char_('-')) >> int_ >> charset::no_case[(lit("days") | lit("day"))];
|
||||
|
||||
date %= charset::no_case[(-year >> month >> daynum)]
|
||||
| (-year >> charset::no_case[lit("easter")])
|
||||
| daynum >> !(lit(':') >> qi::digit)
|
||||
;
|
||||
|
||||
date_with_offsets %= date >> -((char_('+') | char_('-')) >> charset::no_case[wdays] >> qi::no_skip[qi::space]) >> -day_offset;
|
||||
|
||||
monthday_range %= (date_with_offsets >> dash >> date_with_offsets)
|
||||
| (date_with_offsets >> '+')
|
||||
| date_with_offsets
|
||||
| charset::no_case[(-year >> month >> dash >> month >> '/' >> int_)]
|
||||
| charset::no_case[(-year >> month >> dash >> month)]
|
||||
| charset::no_case[(-year >> month)]
|
||||
;
|
||||
|
||||
month_range %= charset::no_case[(month >> dash >> month)]
|
||||
| charset::no_case[month]
|
||||
;
|
||||
|
||||
main %= (monthday_range % ',') | (month_range % ',');
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(month_range);
|
||||
BOOST_SPIRIT_DEBUG_NODE(monthday_range);
|
||||
BOOST_SPIRIT_DEBUG_NODE(date_with_offsets);
|
||||
BOOST_SPIRIT_DEBUG_NODE(date);
|
||||
BOOST_SPIRIT_DEBUG_NODE(day_offset);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Iterator>
|
||||
class weekday_selector : public qi::grammar<Iterator, osmoh::TWeekdays(), space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, uint8_t(), space_type> nth;
|
||||
qi::rule<Iterator, uint16_t(), space_type> nth_entry;
|
||||
qi::rule<Iterator, int32_t(), space_type, qi::locals<int8_t>> day_offset;
|
||||
qi::rule<Iterator, space_type> holyday;
|
||||
qi::rule<Iterator, space_type> holiday_sequence;
|
||||
qi::rule<Iterator, osmoh::Weekday(), space_type> weekday_range;
|
||||
qi::rule<Iterator, osmoh::TWeekdays(), space_type> weekday_sequence;
|
||||
qi::rule<Iterator, osmoh::TWeekdays(), space_type> main;
|
||||
public:
|
||||
weekday_selector() : weekday_selector::base_type(main)
|
||||
{
|
||||
using qi::_a;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_val;
|
||||
using qi::lit;
|
||||
using qi::ushort_;
|
||||
using boost::phoenix::at_c;
|
||||
|
||||
nth %= ushort_(1) | ushort_(2) | ushort_(3) | ushort_(4) | ushort_(5);
|
||||
|
||||
nth_entry = (nth >> dash >> nth) [_val |= ((2 << ((_2-1)-(_1-1))) - 1) << (_1-1)]
|
||||
| (lit('-') >> nth) [_val |= (0x0100 << (_1 - 1))]
|
||||
| nth [_val |= (1 << (_1 - 1))]
|
||||
;
|
||||
|
||||
day_offset = (lit('+')[_a = 1] | lit('-') [_a = -1]) >> ushort_[_val = _1*_a] >> charset::no_case[(lit(L"days") | lit(L"day"))];
|
||||
holyday %= (charset::no_case[lit(L"SH")] >> -day_offset) | charset::no_case[lit(L"PH")];
|
||||
holiday_sequence %= holyday % ',';
|
||||
weekday_range = (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)]
|
||||
>> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L','
|
||||
>> L']' >> day_offset[at_c<2>(_val) = _1])
|
||||
| (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)] >> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L',' >> L']')
|
||||
| charset::no_case[(wdays >> dash >> wdays)] [at_c<0>(_val) |= ((2 << ((_2)-(_1))) - 1) << (_1)]
|
||||
| charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)]
|
||||
;
|
||||
|
||||
weekday_sequence %= (weekday_range % L',') >> !qi::no_skip[charset::alpha] >> -lit(L':');
|
||||
|
||||
main = (holiday_sequence >> -lit(L',') >> weekday_sequence[_val = _1])
|
||||
| weekday_sequence[_val = _1] >> -(-lit(L',') >> holiday_sequence)
|
||||
| holiday_sequence
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(weekday_sequence);
|
||||
BOOST_SPIRIT_DEBUG_NODE(weekday_range);
|
||||
BOOST_SPIRIT_DEBUG_NODE(holiday_sequence);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class time_selector : public qi::grammar<Iterator, osmoh::TTimeSpans(), space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, osmoh::Time(), space_type, qi::locals<uint8_t>> hour_minutes;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type, qi::locals<uint8_t>> extended_hour_minutes;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type> variable_time;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type> extended_time;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type> time;
|
||||
qi::rule<Iterator, osmoh::TimeSpan(), space_type> timespan;
|
||||
qi::rule<Iterator, osmoh::TTimeSpans(), space_type> main;
|
||||
|
||||
class validate_timespan_impl
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
struct result { typedef bool type; };
|
||||
|
||||
bool operator() (osmoh::TimeSpan const & ts) const
|
||||
{
|
||||
using boost::posix_time::ptime;
|
||||
using boost::posix_time::time_duration;
|
||||
using boost::posix_time::hours;
|
||||
using boost::posix_time::minutes;
|
||||
using boost::posix_time::time_period;
|
||||
|
||||
bool result = true;
|
||||
if (ts.period.flags)
|
||||
{
|
||||
time_period tp = osmoh::make_time_period(boost::gregorian::day_clock::local_day(), ts);
|
||||
result = (tp.length() >= time_duration(ts.period.hours, ts.period.minutes, 0 /* seconds */));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
time_selector() : time_selector::base_type(main)
|
||||
{
|
||||
using qi::int_;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_a;
|
||||
using qi::_val;
|
||||
using qi::lit;
|
||||
using qi::_pass;
|
||||
using charset::char_;
|
||||
using boost::phoenix::at_c;
|
||||
|
||||
phx::function<validate_timespan_impl> const validate_timespan = validate_timespan_impl();
|
||||
|
||||
hour_minutes = hours[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::eHours]
|
||||
|| (((lit(':') | lit(":") | lit('.')) >> minutes[at_c<1>(_val) = _1,
|
||||
at_c<2>(_val) |= osmoh::Time::eMinutes])
|
||||
^ charset::no_case[lit('h') | lit("hs") | lit("hrs") | lit("uhr")]
|
||||
^ (charset::no_case[lit("am")][_a = 0] | charset::no_case[lit("pm")][_a = 1])
|
||||
[phx::if_(at_c<0>(_val) <= 12)[at_c<0>(_val) += (12 * _a)]])
|
||||
;
|
||||
|
||||
extended_hour_minutes = exthours[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::eHours]
|
||||
|| (((lit(':') | lit(":") | lit('.')) >> minutes[at_c<1>(_val) = _1,
|
||||
at_c<2>(_val) |= osmoh::Time::eMinutes])
|
||||
^ charset::no_case[lit('h') | lit("hs") | lit("hrs") | lit("uhr")]
|
||||
^ (charset::no_case[lit("am")][_a = 0] | charset::no_case[lit("pm")][_a = 1])
|
||||
[phx::if_(at_c<0>(_val) <= 12)[at_c<0>(_val) += (12 * _a)]])
|
||||
;
|
||||
|
||||
variable_time =
|
||||
(lit('(')
|
||||
>> charset::no_case[event][at_c<2>(_val) |= _1]
|
||||
>> (
|
||||
char_('+')[at_c<2>(_val) |= osmoh::Time::ePlus]
|
||||
| char_('-')[at_c<2>(_val) |= osmoh::Time::eMinus]
|
||||
)
|
||||
>> hour_minutes[at_c<2>(_1) |= at_c<2>(_val), _val = _1]
|
||||
>> lit(')')
|
||||
)
|
||||
| charset::no_case[event][at_c<2>(_val) |= _1]
|
||||
;
|
||||
|
||||
extended_time %= extended_hour_minutes | variable_time;
|
||||
|
||||
time %= hour_minutes | variable_time;
|
||||
|
||||
timespan =
|
||||
(time >> dash >> extended_time >> L'/' >> hour_minutes)
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::eExt,
|
||||
at_c<3>(_val) = _3]
|
||||
| (time >> dash >> extended_time >> L'/' >> minutes)
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::eExt,
|
||||
at_c<1>(at_c<3>(_val)) = _3, at_c<2>(at_c<3>(_val)) = osmoh::Time::eMinutes]
|
||||
| (time >> dash >> extended_time >> char_(L'+'))
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::ePlus]
|
||||
| (time >> dash >> extended_time)
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2]
|
||||
| (time >> char_(L'+'))
|
||||
[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::ePlus]
|
||||
| time [at_c<0>(_val) = _1]
|
||||
;
|
||||
|
||||
main %= timespan[_pass = validate_timespan(_1)] % ',';
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(timespan);
|
||||
BOOST_SPIRIT_DEBUG_NODE(time);
|
||||
BOOST_SPIRIT_DEBUG_NODE(extended_time);
|
||||
BOOST_SPIRIT_DEBUG_NODE(variable_time);
|
||||
BOOST_SPIRIT_DEBUG_NODE(extended_hour_minutes);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class selectors : public qi::grammar<Iterator, osmoh::TimeRule(), space_type>
|
||||
{
|
||||
protected:
|
||||
weekday_selector<Iterator> weekday_selector;
|
||||
time_selector<Iterator> time_selector;
|
||||
year_selector<Iterator> year_selector;
|
||||
month_selector<Iterator> month_selector;
|
||||
week_selector<Iterator> week_selector;
|
||||
|
||||
qi::rule<Iterator, std::string(), space_type> comment;
|
||||
qi::rule<Iterator, osmoh::TimeRule(), space_type> small_range_selectors;
|
||||
qi::rule<Iterator, space_type> wide_range_selectors;
|
||||
qi::rule<Iterator, osmoh::TimeRule(), space_type> main;
|
||||
public:
|
||||
selectors() : selectors::base_type(main)
|
||||
{
|
||||
using qi::_1;
|
||||
using qi::_val;
|
||||
using qi::lit;
|
||||
using qi::lexeme;
|
||||
using charset::char_;
|
||||
using boost::phoenix::at_c;
|
||||
using osmoh::State;
|
||||
|
||||
comment %= lexeme['"' >> +(char_ - '"') >> '"'];
|
||||
wide_range_selectors = -year_selector >> -month_selector >> -week_selector >> -lit(':') | (comment >> ':');
|
||||
small_range_selectors = -weekday_selector[at_c<0>(_val) = _1] >> -( lit("24/7") | time_selector[at_c<1>(_val) = _1]);
|
||||
|
||||
main =
|
||||
(
|
||||
lit(L"24/7")
|
||||
| lit(L"24時間営業")
|
||||
| lit(L"7/24")
|
||||
| lit(L"24時間")
|
||||
| charset::no_case[lit(L"daily 24/7")]
|
||||
| charset::no_case[lit(L"24 hours")]
|
||||
| charset::no_case[lit(L"24 horas")]
|
||||
| charset::no_case[lit(L"круглосуточно")]
|
||||
| charset::no_case[lit(L"24 часа")]
|
||||
| charset::no_case[lit(L"24 hrs")]
|
||||
| charset::no_case[lit(L"nonstop")]
|
||||
| charset::no_case[lit(L"24hrs")]
|
||||
| charset::no_case[lit(L"open 24 hours")]
|
||||
| charset::no_case[lit(L"24 stunden")]
|
||||
)[at_c<0>(at_c<2>(_val)) = State::eOpen]
|
||||
| (-wide_range_selectors >> small_range_selectors[_val = _1, at_c<0>(at_c<2>(_val)) = State::eOpen])
|
||||
;
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(small_range_selectors);
|
||||
BOOST_SPIRIT_DEBUG_NODE(wide_range_selectors);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class time_domain : public qi::grammar<Iterator, osmoh::TTimeRules(), space_type, qi::locals<qi::rule<Iterator, space_type>*>>
|
||||
{
|
||||
protected:
|
||||
selectors<Iterator> selector_sequence;
|
||||
|
||||
qi::rule<Iterator, std::string(), space_type> comment;
|
||||
qi::rule<Iterator, space_type> separator;
|
||||
qi::rule<Iterator, space_type> base_separator;
|
||||
qi::rule<Iterator, osmoh::TimeRule(), space_type> rule_sequence;
|
||||
qi::rule<Iterator, osmoh::State(), space_type> rule_modifier;
|
||||
qi::rule<Iterator, osmoh::TTimeRules(), space_type, qi::locals<qi::rule<Iterator, space_type>*>> main;
|
||||
|
||||
public:
|
||||
time_domain() : time_domain::base_type(main)
|
||||
{
|
||||
using qi::lit;
|
||||
using qi::lexeme;
|
||||
using qi::_1;
|
||||
using qi::_a;
|
||||
using qi::_val;
|
||||
using charset::char_;
|
||||
using boost::phoenix::at_c;
|
||||
using qi::lazy;
|
||||
using qi::eps;
|
||||
using osmoh::State;
|
||||
|
||||
comment %= lexeme['"' >> +(char_ - '"') >> '"'] | lexeme['(' >> +(char_ - ')') >> ')'];
|
||||
base_separator = lit(';') | lit("||");
|
||||
separator = lit(';') | lit("||") | lit(',');
|
||||
|
||||
rule_modifier =
|
||||
(charset::no_case[lit("open")][at_c<0>(_val) = State::eOpen] >> -comment[at_c<1>(_val) = _1])
|
||||
| ((charset::no_case[lit("closed") | lit("off")])[at_c<0>(_val) = State::eClosed] >> -comment[at_c<1>(_val) = _1])
|
||||
| (charset::no_case[lit("unknown")][at_c<0>(_val) = State::eUnknown] >> -comment[at_c<1>(_val) = _1])
|
||||
| comment[at_c<0>(_val) = State::eUnknown, at_c<1>(_val) = _1]
|
||||
;
|
||||
|
||||
rule_sequence = selector_sequence[_val = _1]
|
||||
>> -rule_modifier[at_c<2>(_val) = _1, at_c<3>(_val) = 1];
|
||||
|
||||
main %= -(lit("opening_hours") >> lit('='))
|
||||
>> rule_sequence[_a = phx::val(&base_separator),
|
||||
phx::if_(at_c<3>(_1) || phx::size(at_c<1>(_1)))[_a = phx::val(&separator)]] % lazy(*_a);
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(rule_sequence);
|
||||
BOOST_SPIRIT_DEBUG_NODE(rule_modifier);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
inline bool parse_timerange(Iterator first, Iterator last, osmoh::TTimeRules & context)
|
||||
{
|
||||
using qi::phrase_parse;
|
||||
using charset::space;
|
||||
|
||||
time_domain<Iterator> time_domain;
|
||||
|
||||
bool r = phrase_parse(
|
||||
first, /* start iterator */
|
||||
last, /* end iterator */
|
||||
time_domain, /* the parser */
|
||||
space, /* the skip-parser */
|
||||
context /* result storage */
|
||||
);
|
||||
|
||||
if (first != last) // fail if we did not get a full match
|
||||
return false;
|
||||
return r;
|
||||
}
|
||||
} // namespace parsing
|
||||
} // namespace osmoh
|
|
@ -22,37 +22,12 @@
|
|||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "osm_time_range.hpp"
|
||||
#include "osm_parsers.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <vector>
|
||||
#include <codecvt>
|
||||
|
||||
//#define BOOST_SPIRIT_DEBUG 1
|
||||
#define BOOST_SPIRIT_USE_PHOENIX_V3
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
#include <boost/spirit/repository/include/qi_subrule.hpp>
|
||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
||||
#include <boost/spirit/include/phoenix_fusion.hpp>
|
||||
#include <boost/spirit/include/phoenix_stl.hpp>
|
||||
#include <boost/spirit/include/phoenix_statement.hpp>
|
||||
#include <boost/spirit/include/phoenix_bind.hpp>
|
||||
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/date_time/gregorian/gregorian.hpp>
|
||||
#pragma clang diagnostic pop
|
||||
#else
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/date_time/gregorian/gregorian.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace osmoh
|
||||
{
|
||||
|
||||
|
@ -153,641 +128,29 @@ std::ostream & operator << (std::ostream & s, TimeRule const & w)
|
|||
for (auto const & e : w.timespan)
|
||||
s << e;
|
||||
|
||||
std::cout << "Weekdays size " << w.weekdays.size() <<
|
||||
" Timespan size " << w.timespan.size() << std::endl;
|
||||
return s << w.state;
|
||||
}
|
||||
} // namespace osmoh
|
||||
|
||||
boost::posix_time::time_period make_time_period(boost::gregorian::date const & d, osmoh::TimeSpan const & ts)
|
||||
|
||||
namespace
|
||||
{
|
||||
bool check_timespan(osmoh::TimeSpan const &ts, boost::gregorian::date const & d, boost::posix_time::ptime const & p)
|
||||
{
|
||||
using boost::gregorian::days;
|
||||
using boost::posix_time::ptime;
|
||||
using boost::posix_time::hours;
|
||||
using boost::posix_time::minutes;
|
||||
using boost::posix_time::time_period;
|
||||
|
||||
/// TODO(yershov@): Need create code for calculate real values
|
||||
ptime sunrise(d, hours(6));
|
||||
ptime sunset(d, hours(19));
|
||||
|
||||
ptime t1, t2;
|
||||
|
||||
if (ts.from.flags & osmoh::Time::eSunrise)
|
||||
t1 = sunrise;
|
||||
else if (ts.from.flags & osmoh::Time::eSunset)
|
||||
t1 = sunset;
|
||||
else
|
||||
t1 = ptime(d, hours((ts.from.flags & osmoh::Time::eHours) ? ts.from.hours : 0) + minutes((ts.from.flags & osmoh::Time::eMinutes) ? ts.from.minutes : 0));
|
||||
|
||||
t2 = t1;
|
||||
|
||||
if (ts.to.flags & osmoh::Time::eSunrise)
|
||||
t2 = sunrise;
|
||||
else if (ts.to.flags & osmoh::Time::eSunset)
|
||||
t2 = sunset;
|
||||
else
|
||||
{
|
||||
t2 = ptime(d, hours((ts.to.flags & osmoh::Time::eHours) ? ts.to.hours : 24) + minutes((ts.to.flags & osmoh::Time::eMinutes) ? ts.to.minutes : 0));
|
||||
if (t2 < t1)
|
||||
t2 += hours(24);
|
||||
}
|
||||
|
||||
return time_period(t1, t2);
|
||||
}
|
||||
|
||||
} // namespace osmoh
|
||||
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::Time,
|
||||
(uint8_t, hours)
|
||||
(uint8_t, minutes)
|
||||
(uint8_t, flags)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::TimeSpan,
|
||||
(osmoh::Time, from)
|
||||
(osmoh::Time, to)
|
||||
(uint8_t, flags)
|
||||
(osmoh::Time, period)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::Weekday,
|
||||
(uint8_t, weekdays)
|
||||
(uint16_t, nth)
|
||||
(int32_t, offset)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::State,
|
||||
(uint8_t, state)
|
||||
(std::string, comment)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
osmoh::TimeRule,
|
||||
(osmoh::TWeekdays, weekdays)
|
||||
(osmoh::TTimeSpans, timespan)
|
||||
(osmoh::State, state)
|
||||
(uint8_t, int_flags)
|
||||
)
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
namespace phx = boost::phoenix;
|
||||
namespace repo = boost::spirit::repository;
|
||||
|
||||
namespace charset = boost::spirit::standard_wide;
|
||||
using space_type = charset::space_type;
|
||||
|
||||
|
||||
class test_impl
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
struct result { typedef void type; };
|
||||
|
||||
template <typename Arg>
|
||||
void operator() (const Arg & a) const
|
||||
{
|
||||
std::cout << a << " \t(" << typeid(a).name() << ")" << std::endl;
|
||||
}
|
||||
};
|
||||
phx::function<test_impl> const test = test_impl();
|
||||
|
||||
class dash_ : public qi::symbols<wchar_t>
|
||||
{
|
||||
public:
|
||||
dash_()
|
||||
{
|
||||
add
|
||||
(L"-")
|
||||
/* not standard */
|
||||
(L"–")(L"—")(L"-")(L"~")(L"~")(L"〜")(L"to")(L"às")(L"ás")(L"as")(L"a")(L"ate")(L"bis")
|
||||
;
|
||||
}
|
||||
} dash;
|
||||
|
||||
class event_ : public qi::symbols<wchar_t, uint8_t>
|
||||
{
|
||||
public:
|
||||
event_()
|
||||
{
|
||||
add
|
||||
(L"dawn", osmoh::Time::eSunrise)(L"sunrise", osmoh::Time::eSunrise)(L"sunset", osmoh::Time::eSunset)(L"dusk", osmoh::Time::eSunset)
|
||||
;
|
||||
}
|
||||
} event;
|
||||
|
||||
struct wdays_ : qi::symbols<wchar_t, unsigned>
|
||||
{
|
||||
wdays_()
|
||||
{
|
||||
add
|
||||
(L"mo", 0)(L"tu", 1)(L"we", 2)(L"th", 3)(L"fr", 4)(L"sa", 5)(L"su", 6) // en
|
||||
(L"mon", 0)(L"tue", 1)(L"wed", 2)(L"thu", 3)(L"fri", 4)(L"sat", 5)(L"sun", 6) // en
|
||||
(L"пн", 0)(L"вт", 1)(L"ср", 2)(L"чт", 3)(L"пт", 4)(L"сб", 5)(L"вс", 6) // ru
|
||||
(L"пн.", 0)(L"вт.", 1)(L"ср.", 2)(L"чт.", 3)(L"пт.", 4)(L"сб.", 5)(L"вс.", 6) // ru
|
||||
(L"lu", 0)(L"ma", 1)(L"me", 2)(L"je", 3)(L"ve", 4)(L"sa", 5)(L"di", 6) // fr
|
||||
(L"lu", 0)(L"ma", 1)(L"me", 2)(L"gi", 3)(L"ve", 4)(L"sa", 5)(L"do", 6) // it
|
||||
(L"lu", 0)(L"ma", 1)(L"mi", 2)(L"ju", 3)(L"vie", 4)(L"sá", 5)(L"do", 6) // sp
|
||||
(L"週一", 0)(L"週二", 1)(L"週三", 2)(L"週四", 3)(L"週五", 4)(L"週六", 5)(L"週日", 6) // ch traditional
|
||||
(L"senin", 0)(L"selasa", 1)(L"rabu", 2)(L"kamis", 3)(L"jum'at", 4)(L"sabtu", 5)(L"minggu", 6) // indonesian
|
||||
|
||||
(L"wd", 2)
|
||||
|
||||
;
|
||||
}
|
||||
} wdays;
|
||||
|
||||
struct month_ : qi::symbols<wchar_t, unsigned>
|
||||
{
|
||||
month_()
|
||||
{
|
||||
add
|
||||
(L"jan", 1)(L"feb", 2)(L"mar", 3)(L"apr", 4)(L"may", 5)(L"jun", 6)
|
||||
(L"jul", 7)(L"aug", 8)(L"sep", 9)(L"oct", 10)(L"nov", 11)(L"dec", 12)
|
||||
;
|
||||
}
|
||||
} month;
|
||||
|
||||
struct hours_ : qi::symbols<char, uint8_t>
|
||||
{
|
||||
hours_()
|
||||
{
|
||||
add
|
||||
( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)
|
||||
;
|
||||
}
|
||||
} hours;
|
||||
|
||||
struct exthours_ : qi::symbols<char, uint8_t>
|
||||
{
|
||||
exthours_()
|
||||
{
|
||||
add
|
||||
( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39)
|
||||
("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)
|
||||
;
|
||||
}
|
||||
} exthours;
|
||||
|
||||
struct minutes_ : qi::symbols<char, uint8_t>
|
||||
{
|
||||
minutes_()
|
||||
{
|
||||
add
|
||||
( "0", 0)( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9) /* not standard */
|
||||
("00", 0)("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39)
|
||||
("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)("49", 49)
|
||||
("50", 50)("51", 51)("52", 52)("53", 53)("54", 54)("55", 55)("56", 56)("57", 57)("58", 58)("59", 59)
|
||||
;
|
||||
}
|
||||
} minutes;
|
||||
|
||||
struct weeknum_ : qi::symbols<char, unsigned>
|
||||
{
|
||||
weeknum_()
|
||||
{
|
||||
add
|
||||
( "1", 1)( "2", 2)( "3", 3)( "4", 4)( "5", 5)( "6", 6)( "7", 7)( "8", 8)( "9", 9)
|
||||
("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
("30", 30)("31", 31)("32", 32)("33", 33)("34", 34)("35", 35)("36", 36)("37", 37)("38", 38)("39", 39)
|
||||
("40", 40)("41", 41)("42", 42)("43", 43)("44", 44)("45", 45)("46", 46)("47", 47)("48", 48)("49", 49)
|
||||
("50", 50)("51", 51)("52", 52)("53", 53)
|
||||
;
|
||||
}
|
||||
} weeknum;
|
||||
|
||||
struct daynum_ : qi::symbols<char, unsigned>
|
||||
{
|
||||
daynum_()
|
||||
{
|
||||
add
|
||||
("1", 1)("2", 2)("3", 3)("4", 4)("5", 5)("6", 6)("7", 7)("8", 8)("9", 9)
|
||||
("01", 1)("02", 2)("03", 3)("04", 4)("05", 5)("06", 6)("07", 7)("08", 8)("09", 9)
|
||||
("10", 10)("11", 11)("12", 12)("13", 13)("14", 14)("15", 15)("16", 16)("17", 17)("18", 18)("19", 19)
|
||||
("20", 20)("21", 21)("22", 22)("23", 23)("24", 24)("25", 25)("26", 26)("27", 27)("28", 28)("29", 29)
|
||||
("30", 30)("31", 31)
|
||||
;
|
||||
}
|
||||
} daynum;
|
||||
|
||||
template <class Iterator>
|
||||
class year_selector : public qi::grammar<Iterator, space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, space_type> year;
|
||||
qi::rule<Iterator, space_type> year_range;
|
||||
qi::rule<Iterator, space_type> main;
|
||||
public:
|
||||
year_selector() : year_selector::base_type(main)
|
||||
{
|
||||
using qi::uint_;
|
||||
using qi::lit;
|
||||
using charset::char_;
|
||||
|
||||
static const qi::int_parser<unsigned, 10, 4, 4> _4digit = {};
|
||||
|
||||
year %= _4digit;
|
||||
year_range %= (year >> dash >> year >> '/' >> uint_)
|
||||
| (year >> dash >> year)
|
||||
| year >> char_('+')
|
||||
| year
|
||||
;
|
||||
main %= year_range % ',';
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class week_selector : public qi::grammar<Iterator, space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, space_type> week;
|
||||
qi::rule<Iterator, space_type> year_range;
|
||||
qi::rule<Iterator, space_type> main;
|
||||
public:
|
||||
week_selector() : week_selector::base_type(main)
|
||||
{
|
||||
using qi::uint_;
|
||||
using qi::lit;
|
||||
using charset::char_;
|
||||
|
||||
week %= (weeknum >> dash >> weeknum >> '/' >> uint_)
|
||||
| (weeknum >> dash >> weeknum)
|
||||
| weeknum
|
||||
;
|
||||
|
||||
main %= charset::no_case[lit("week")] >> week % ',';
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class month_selector : public qi::grammar<Iterator, space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, space_type> date;
|
||||
qi::rule<Iterator, space_type> day_offset;
|
||||
qi::rule<Iterator, space_type> date_with_offsets;
|
||||
qi::rule<Iterator, space_type> monthday_range;
|
||||
qi::rule<Iterator, space_type> month_range;
|
||||
qi::rule<Iterator, space_type> main;
|
||||
public:
|
||||
month_selector() : month_selector::base_type(main)
|
||||
{
|
||||
using qi::int_;
|
||||
using qi::lit;
|
||||
using qi::double_;
|
||||
using qi::lexeme;
|
||||
using charset::char_;
|
||||
|
||||
static const qi::int_parser<unsigned, 10, 4, 4> year = {};
|
||||
|
||||
day_offset %= (char_('+') | char_('-')) >> int_ >> charset::no_case[(lit("days") | lit("day"))];
|
||||
|
||||
date %= charset::no_case[(-year >> month >> daynum)]
|
||||
| (-year >> charset::no_case[lit("easter")])
|
||||
| daynum >> !(lit(':') >> qi::digit)
|
||||
;
|
||||
|
||||
date_with_offsets %= date >> -((char_('+') | char_('-')) >> charset::no_case[wdays] >> qi::no_skip[qi::space]) >> -day_offset;
|
||||
|
||||
monthday_range %= (date_with_offsets >> dash >> date_with_offsets)
|
||||
| (date_with_offsets >> '+')
|
||||
| date_with_offsets
|
||||
| charset::no_case[(-year >> month >> dash >> month >> '/' >> int_)]
|
||||
| charset::no_case[(-year >> month >> dash >> month)]
|
||||
| charset::no_case[(-year >> month)]
|
||||
;
|
||||
|
||||
month_range %= charset::no_case[(month >> dash >> month)]
|
||||
| charset::no_case[month]
|
||||
;
|
||||
|
||||
main %= (monthday_range % ',') | (month_range % ',');
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(month_range);
|
||||
BOOST_SPIRIT_DEBUG_NODE(monthday_range);
|
||||
BOOST_SPIRIT_DEBUG_NODE(date_with_offsets);
|
||||
BOOST_SPIRIT_DEBUG_NODE(date);
|
||||
BOOST_SPIRIT_DEBUG_NODE(day_offset);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Iterator>
|
||||
class weekday_selector : public qi::grammar<Iterator, osmoh::TWeekdays(), space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, uint8_t(), space_type> nth;
|
||||
qi::rule<Iterator, uint16_t(), space_type> nth_entry;
|
||||
qi::rule<Iterator, int32_t(), space_type, qi::locals<int8_t>> day_offset;
|
||||
qi::rule<Iterator, space_type> holyday;
|
||||
qi::rule<Iterator, space_type> holiday_sequence;
|
||||
qi::rule<Iterator, osmoh::Weekday(), space_type> weekday_range;
|
||||
qi::rule<Iterator, osmoh::TWeekdays(), space_type> weekday_sequence;
|
||||
qi::rule<Iterator, osmoh::TWeekdays(), space_type> main;
|
||||
public:
|
||||
weekday_selector() : weekday_selector::base_type(main)
|
||||
{
|
||||
using qi::_a;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_val;
|
||||
using qi::lit;
|
||||
using qi::ushort_;
|
||||
using boost::phoenix::at_c;
|
||||
|
||||
nth %= ushort_(1) | ushort_(2) | ushort_(3) | ushort_(4) | ushort_(5);
|
||||
|
||||
nth_entry = (nth >> dash >> nth) [_val |= ((2 << ((_2-1)-(_1-1))) - 1) << (_1-1)]
|
||||
| (lit('-') >> nth) [_val |= (0x0100 << (_1 - 1))]
|
||||
| nth [_val |= (1 << (_1 - 1))]
|
||||
;
|
||||
|
||||
day_offset = (lit('+')[_a = 1] | lit('-') [_a = -1]) >> ushort_[_val = _1*_a] >> charset::no_case[(lit(L"days") | lit(L"day"))];
|
||||
holyday %= (charset::no_case[lit(L"SH")] >> -day_offset) | charset::no_case[lit(L"PH")];
|
||||
holiday_sequence %= holyday % ',';
|
||||
weekday_range = (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)]
|
||||
>> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L','
|
||||
>> L']' >> day_offset[at_c<2>(_val) = _1])
|
||||
| (charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)] >> L'[' >> nth_entry[at_c<1>(_val) |= _1] % L',' >> L']')
|
||||
| charset::no_case[(wdays >> dash >> wdays)] [at_c<0>(_val) |= ((2 << ((_2)-(_1))) - 1) << (_1)]
|
||||
| charset::no_case[wdays][at_c<0>(_val) |= (1<<_1)]
|
||||
;
|
||||
|
||||
weekday_sequence %= (weekday_range % L',') >> !qi::no_skip[charset::alpha] >> -lit(L':');
|
||||
|
||||
main = (holiday_sequence >> -lit(L',') >> weekday_sequence[_val = _1])
|
||||
| weekday_sequence[_val = _1] >> -(-lit(L',') >> holiday_sequence)
|
||||
| holiday_sequence
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(weekday_sequence);
|
||||
BOOST_SPIRIT_DEBUG_NODE(weekday_range);
|
||||
BOOST_SPIRIT_DEBUG_NODE(holiday_sequence);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class time_selector : public qi::grammar<Iterator, osmoh::TTimeSpans(), space_type>
|
||||
{
|
||||
protected:
|
||||
qi::rule<Iterator, osmoh::Time(), space_type, qi::locals<uint8_t>> hour_minutes;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type, qi::locals<uint8_t>> extended_hour_minutes;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type> variable_time;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type> extended_time;
|
||||
qi::rule<Iterator, osmoh::Time(), space_type> time;
|
||||
qi::rule<Iterator, osmoh::TimeSpan(), space_type> timespan;
|
||||
qi::rule<Iterator, osmoh::TTimeSpans(), space_type> main;
|
||||
|
||||
class validate_timespan_impl
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
struct result { typedef bool type; };
|
||||
|
||||
bool operator() (osmoh::TimeSpan const & ts) const
|
||||
{
|
||||
using boost::posix_time::ptime;
|
||||
using boost::posix_time::time_duration;
|
||||
using boost::posix_time::hours;
|
||||
using boost::posix_time::minutes;
|
||||
using boost::posix_time::time_period;
|
||||
|
||||
bool result = true;
|
||||
if (ts.period.flags)
|
||||
{
|
||||
time_period tp = osmoh::make_time_period(boost::gregorian::day_clock::local_day(), ts);
|
||||
result = (tp.length() >= time_duration(ts.period.hours, ts.period.minutes, 0 /* seconds */));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
time_selector() : time_selector::base_type(main)
|
||||
{
|
||||
using qi::int_;
|
||||
using qi::_1;
|
||||
using qi::_2;
|
||||
using qi::_3;
|
||||
using qi::_a;
|
||||
using qi::_val;
|
||||
using qi::lit;
|
||||
using qi::_pass;
|
||||
using charset::char_;
|
||||
using boost::phoenix::at_c;
|
||||
|
||||
phx::function<validate_timespan_impl> const validate_timespan = validate_timespan_impl();
|
||||
|
||||
hour_minutes = hours[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::eHours]
|
||||
|| (((lit(':') | lit(":") | lit('.')) >> minutes[at_c<1>(_val) = _1,
|
||||
at_c<2>(_val) |= osmoh::Time::eMinutes])
|
||||
^ charset::no_case[lit('h') | lit("hs") | lit("hrs") | lit("uhr")]
|
||||
^ (charset::no_case[lit("am")][_a = 0] | charset::no_case[lit("pm")][_a = 1])
|
||||
[phx::if_(at_c<0>(_val) <= 12)[at_c<0>(_val) += (12 * _a)]])
|
||||
;
|
||||
|
||||
extended_hour_minutes = exthours[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::eHours]
|
||||
|| (((lit(':') | lit(":") | lit('.')) >> minutes[at_c<1>(_val) = _1,
|
||||
at_c<2>(_val) |= osmoh::Time::eMinutes])
|
||||
^ charset::no_case[lit('h') | lit("hs") | lit("hrs") | lit("uhr")]
|
||||
^ (charset::no_case[lit("am")][_a = 0] | charset::no_case[lit("pm")][_a = 1])
|
||||
[phx::if_(at_c<0>(_val) <= 12)[at_c<0>(_val) += (12 * _a)]])
|
||||
;
|
||||
|
||||
variable_time =
|
||||
(lit('(')
|
||||
>> charset::no_case[event][at_c<2>(_val) |= _1]
|
||||
>> (
|
||||
char_('+')[at_c<2>(_val) |= osmoh::Time::ePlus]
|
||||
| char_('-')[at_c<2>(_val) |= osmoh::Time::eMinus]
|
||||
)
|
||||
>> hour_minutes[at_c<2>(_1) |= at_c<2>(_val), _val = _1]
|
||||
>> lit(')')
|
||||
)
|
||||
| charset::no_case[event][at_c<2>(_val) |= _1]
|
||||
;
|
||||
|
||||
extended_time %= extended_hour_minutes | variable_time;
|
||||
|
||||
time %= hour_minutes | variable_time;
|
||||
|
||||
timespan =
|
||||
(time >> dash >> extended_time >> L'/' >> hour_minutes)
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::eExt,
|
||||
at_c<3>(_val) = _3]
|
||||
| (time >> dash >> extended_time >> L'/' >> minutes)
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::eExt,
|
||||
at_c<1>(at_c<3>(_val)) = _3, at_c<2>(at_c<3>(_val)) = osmoh::Time::eMinutes]
|
||||
| (time >> dash >> extended_time >> char_(L'+'))
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2, at_c<2>(_val) |= osmoh::Time::ePlus]
|
||||
| (time >> dash >> extended_time)
|
||||
[at_c<0>(_val) = _1, at_c<1>(_val) = _2]
|
||||
| (time >> char_(L'+'))
|
||||
[at_c<0>(_val) = _1, at_c<2>(_val) |= osmoh::Time::ePlus]
|
||||
| time [at_c<0>(_val) = _1]
|
||||
;
|
||||
|
||||
main %= timespan[_pass = validate_timespan(_1)] % ',';
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(timespan);
|
||||
BOOST_SPIRIT_DEBUG_NODE(time);
|
||||
BOOST_SPIRIT_DEBUG_NODE(extended_time);
|
||||
BOOST_SPIRIT_DEBUG_NODE(variable_time);
|
||||
BOOST_SPIRIT_DEBUG_NODE(extended_hour_minutes);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class selectors : public qi::grammar<Iterator, osmoh::TimeRule(), space_type>
|
||||
{
|
||||
protected:
|
||||
weekday_selector<Iterator> weekday_selector;
|
||||
time_selector<Iterator> time_selector;
|
||||
year_selector<Iterator> year_selector;
|
||||
month_selector<Iterator> month_selector;
|
||||
week_selector<Iterator> week_selector;
|
||||
|
||||
qi::rule<Iterator, std::string(), space_type> comment;
|
||||
qi::rule<Iterator, osmoh::TimeRule(), space_type> small_range_selectors;
|
||||
qi::rule<Iterator, space_type> wide_range_selectors;
|
||||
qi::rule<Iterator, osmoh::TimeRule(), space_type> main;
|
||||
public:
|
||||
selectors() : selectors::base_type(main)
|
||||
{
|
||||
using qi::_1;
|
||||
using qi::_val;
|
||||
using qi::lit;
|
||||
using qi::lexeme;
|
||||
using charset::char_;
|
||||
using boost::phoenix::at_c;
|
||||
using osmoh::State;
|
||||
|
||||
comment %= lexeme['"' >> +(char_ - '"') >> '"'];
|
||||
wide_range_selectors = -year_selector >> -month_selector >> -week_selector >> -lit(':') | (comment >> ':');
|
||||
small_range_selectors = -weekday_selector[at_c<0>(_val) = _1] >> -( lit("24/7") | time_selector[at_c<1>(_val) = _1]);
|
||||
|
||||
main =
|
||||
(
|
||||
lit(L"24/7")
|
||||
| lit(L"24時間営業")
|
||||
| lit(L"7/24")
|
||||
| lit(L"24時間")
|
||||
| charset::no_case[lit(L"daily 24/7")]
|
||||
| charset::no_case[lit(L"24 hours")]
|
||||
| charset::no_case[lit(L"24 horas")]
|
||||
| charset::no_case[lit(L"круглосуточно")]
|
||||
| charset::no_case[lit(L"24 часа")]
|
||||
| charset::no_case[lit(L"24 hrs")]
|
||||
| charset::no_case[lit(L"nonstop")]
|
||||
| charset::no_case[lit(L"24hrs")]
|
||||
| charset::no_case[lit(L"open 24 hours")]
|
||||
| charset::no_case[lit(L"24 stunden")]
|
||||
)[at_c<0>(at_c<2>(_val)) = State::eOpen]
|
||||
| (-wide_range_selectors >> small_range_selectors[_val = _1, at_c<0>(at_c<2>(_val)) = State::eOpen])
|
||||
;
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(small_range_selectors);
|
||||
BOOST_SPIRIT_DEBUG_NODE(wide_range_selectors);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
class time_domain : public qi::grammar<Iterator, osmoh::TTimeRules(), space_type, qi::locals<qi::rule<Iterator, space_type>*>>
|
||||
{
|
||||
protected:
|
||||
selectors<Iterator> selector_sequence;
|
||||
|
||||
qi::rule<Iterator, std::string(), space_type> comment;
|
||||
qi::rule<Iterator, space_type> separator;
|
||||
qi::rule<Iterator, space_type> base_separator;
|
||||
qi::rule<Iterator, osmoh::TimeRule(), space_type> rule_sequence;
|
||||
qi::rule<Iterator, osmoh::State(), space_type> rule_modifier;
|
||||
qi::rule<Iterator, osmoh::TTimeRules(), space_type, qi::locals<qi::rule<Iterator, space_type>*>> main;
|
||||
|
||||
public:
|
||||
time_domain() : time_domain::base_type(main)
|
||||
{
|
||||
using qi::lit;
|
||||
using qi::lexeme;
|
||||
using qi::_1;
|
||||
using qi::_a;
|
||||
using qi::_val;
|
||||
using charset::char_;
|
||||
using boost::phoenix::at_c;
|
||||
using qi::lazy;
|
||||
using qi::eps;
|
||||
using osmoh::State;
|
||||
|
||||
comment %= lexeme['"' >> +(char_ - '"') >> '"'] | lexeme['(' >> +(char_ - ')') >> ')'];
|
||||
base_separator = lit(';') | lit("||");
|
||||
separator = lit(';') | lit("||") | lit(',');
|
||||
|
||||
rule_modifier =
|
||||
(charset::no_case[lit("open")][at_c<0>(_val) = State::eOpen] >> -comment[at_c<1>(_val) = _1])
|
||||
| ((charset::no_case[lit("closed") | lit("off")])[at_c<0>(_val) = State::eClosed] >> -comment[at_c<1>(_val) = _1])
|
||||
| (charset::no_case[lit("unknown")][at_c<0>(_val) = State::eUnknown] >> -comment[at_c<1>(_val) = _1])
|
||||
| comment[at_c<0>(_val) = State::eUnknown, at_c<1>(_val) = _1]
|
||||
;
|
||||
|
||||
rule_sequence = selector_sequence[_val = _1]
|
||||
>> -rule_modifier[at_c<2>(_val) = _1, at_c<3>(_val) = 1];
|
||||
|
||||
main %= -(lit("opening_hours") >> lit('='))
|
||||
>> rule_sequence[_a = phx::val(&base_separator),
|
||||
phx::if_(at_c<3>(_1) || phx::size(at_c<1>(_1)))[_a = phx::val(&separator)]] % lazy(*_a);
|
||||
|
||||
BOOST_SPIRIT_DEBUG_NODE(main);
|
||||
BOOST_SPIRIT_DEBUG_NODE(rule_sequence);
|
||||
BOOST_SPIRIT_DEBUG_NODE(rule_modifier);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
bool parse_timerange(Iterator first, Iterator last, osmoh::TTimeRules & context)
|
||||
{
|
||||
using qi::phrase_parse;
|
||||
using charset::space;
|
||||
|
||||
time_domain<Iterator> time_domain;
|
||||
|
||||
bool r = phrase_parse(
|
||||
first, /* start iterator */
|
||||
last, /* end iterator */
|
||||
time_domain, /* the parser */
|
||||
space, /* the skip-parser */
|
||||
context /* result storage */
|
||||
);
|
||||
|
||||
if (first != last) // fail if we did not get a full match
|
||||
return false;
|
||||
return r;
|
||||
time_period tp1 = osmoh::make_time_period(d-days(1), ts);
|
||||
time_period tp2 = osmoh::make_time_period(d, ts);
|
||||
/* very useful in debug */
|
||||
// std::cout << ts << "\t" << tp1 << "(" << p << ")" << (tp1.contains(p) ? " hit" : " miss") << std::endl;
|
||||
// std::cout << ts << "\t" << tp2 << "(" << p << ")" << (tp2.contains(p) ? " hit" : " miss") << std::endl;
|
||||
return tp1.contains(p) || tp2.contains(p);
|
||||
}
|
||||
|
||||
bool check_weekday(osmoh::Weekday const & wd, boost::gregorian::date const & d)
|
||||
|
@ -837,23 +200,8 @@ bool check_weekday(osmoh::Weekday const & wd, boost::gregorian::date const & d)
|
|||
return hit;
|
||||
}
|
||||
|
||||
bool check_timespan(osmoh::TimeSpan const &ts, boost::gregorian::date const & d, boost::posix_time::ptime const & p)
|
||||
{
|
||||
using boost::gregorian::days;
|
||||
using boost::posix_time::ptime;
|
||||
using boost::posix_time::hours;
|
||||
using boost::posix_time::minutes;
|
||||
using boost::posix_time::time_period;
|
||||
|
||||
time_period tp1 = osmoh::make_time_period(d-days(1), ts);
|
||||
time_period tp2 = osmoh::make_time_period(d, ts);
|
||||
/* very useful in debug */
|
||||
// std::cout << ts << "\t" << tp1 << "(" << p << ")" << (tp1.contains(p) ? " hit" : " miss") << std::endl;
|
||||
// std::cout << ts << "\t" << tp2 << "(" << p << ")" << (tp2.contains(p) ? " hit" : " miss") << std::endl;
|
||||
return tp1.contains(p) || tp2.contains(p);
|
||||
}
|
||||
|
||||
bool check_rule(osmoh::TimeRule const & r, std::tm const & stm, std::ostream * hitcontext = nullptr)
|
||||
bool check_rule(osmoh::TimeRule const & r, std::tm const & stm,
|
||||
std::ostream * hitcontext = nullptr)
|
||||
{
|
||||
bool next = false;
|
||||
|
||||
|
@ -896,7 +244,7 @@ OSMTimeRange OSMTimeRange::FromString(std::string const & rules)
|
|||
OSMTimeRange timeRange;
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; // could not work on android
|
||||
std::wstring src = converter.from_bytes(rules); // rules should be wstring
|
||||
timeRange.m_valid = parse_timerange(src.begin(), src.end(), timeRange.m_rules);
|
||||
timeRange.m_valid = osmoh::parsing::parse_timerange(src.begin(), src.end(), timeRange.m_rules);
|
||||
return timeRange;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,9 +113,11 @@ class TimeRule
|
|||
{
|
||||
public:
|
||||
TWeekdays weekdays;
|
||||
TTimeSpans timespan;
|
||||
TTimeSpans timespan; // TODO(mgsergio) rename to timespans
|
||||
State state;
|
||||
uint8_t int_flags = 0;
|
||||
|
||||
friend std::ostream & operator <<(std::ostream & s, TimeRule const & r);
|
||||
};
|
||||
} // namespace osmoh
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue