Rewrite month selector. Did not test yet.

This commit is contained in:
Sergey Magidovich 2015-10-22 17:51:10 +03:00
parent 708f5967af
commit 9f6b97ff15
4 changed files with 203 additions and 92 deletions

View file

@ -137,64 +137,118 @@ using space_type = charset::space_type;
// }
// };
// 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_;
template <typename Iterator>
class month_selector : public qi::grammar<Iterator, TMonthdayRanges(), space_type>
{
protected:
qi::rule<Iterator, int32_t(), space_type, qi::locals<int32_t>> day_offset;
qi::rule<Iterator, DateOffset(), space_type, qi::locals<bool>> date_offset;
// static const qi::int_parser<unsigned, 10, 4, 4> year = {};
qi::rule<Iterator, MonthDay(), space_type> date_left;
qi::rule<Iterator, MonthDay(), space_type> date_right;
qi::rule<Iterator, MonthDay(), space_type> date_from;
qi::rule<Iterator, MonthDay(), space_type> date_to;
qi::rule<Iterator, MonthDay(), space_type> date_from_with_offset;
qi::rule<Iterator, MonthDay(), space_type> date_to_with_offset;
// day_offset %= (char_('+') | char_('-')) >> int_ >> charset::no_case[(lit("days") | lit("day"))];
qi::rule<Iterator, MonthdayRange(), space_type> monthday_range;
qi::rule<Iterator, TMonthdayRanges(), space_type> main;
// date %= charset::no_case[(-year >> month >> daynum)]
// | (-year >> charset::no_case[lit("easter")])
// | daynum >> !(lit(':') >> qi::digit)
// ;
public:
month_selector() : month_selector::base_type(main)
{
using qi::_1;
using qi::_2;
using qi::_3;
using qi::_a;
using qi::_val;
using qi::int_;
using qi::uint_;
using qi::lit;
using qi::double_;
using qi::lexeme;
using charset::char_;
// date_with_offsets %= date >> -((char_('+') | char_('-')) >> charset::no_case[wdays] >> qi::no_skip[qi::space]) >> -day_offset;
static const qi::int_parser<unsigned, 10, 4, 4> year = {};
// 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)]
// ;
day_offset = ((lit('+')[_a = 1] | lit('-')[_a = -1]) >>
int_ >> charset::no_case[(lit("days") | lit("day"))]) [_val = _a * _1];
// month_range %= charset::no_case[(month >> dash >> month)]
// | charset::no_case[month]
// ;
date_offset = ((lit('+')[_a = true] | lit('-')[_a = false]) >> wdays >> day_offset)
[bind(&osmoh::DateOffset::SetWDayOffset, _val, _1),
bind(&osmoh::DateOffset::SetOffset, _val, _2),
bind(&osmoh::DateOffset::SetWDayOffsetPositive, _val, _a)]
| ((lit('+')[_a = true] | lit('-') [_a = false]) >> wdays)
[bind(&osmoh::DateOffset::SetWDayOffset, _val, _1),
bind(&osmoh::DateOffset::SetWDayOffsetPositive, _val, _a)]
| day_offset [bind(&osmoh::DateOffset::SetOffset, _val, _1)]
;
// main %= (monthday_range % ',') | (month_range % ',');
date_left = (year >> charset::no_case[month]) [bind(&osmoh::MonthDay::SetYear, _val, _1),
bind(&osmoh::MonthDay::SetMonth, _val, _2)]
// 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);
| charset::no_case[month] [bind(&osmoh::MonthDay::SetMonth, _val, _1)]
;
// }
// };
date_right = charset::no_case[month] [bind(&osmoh::MonthDay::SetMonth, _val, _1)]
;
date_from = (date_left >> (daynum >> !(lit(':') >> qi::digit)))
[_val = _1, bind(&osmoh::MonthDay::SetDayNum, _val, _2)]
| (year >> charset::no_case[lit("easter")]) [bind(&osmoh::MonthDay::SetYear, _val, _1),
bind(&osmoh::MonthDay::SetVariableDate, _val,
MonthDay::EVariableDate::Easter)]
| charset::no_case[lit("easter")] [bind(&osmoh::MonthDay::SetVariableDate, _val,
MonthDay::EVariableDate::Easter)]
;
date_to = date_from [_val = _1]
| (daynum >> !(lit(':') >> qi::digit)) [bind(&osmoh::MonthDay::SetDayNum, _val, _1)]
;
date_from_with_offset = (date_from >> date_offset)
[_val = _1, bind(&osmoh::MonthDay::SetOffset, _val, _2)]
| date_from [_val = _1]
;
date_to_with_offset = (date_to >> date_offset)
[_val = _1, bind(&osmoh::MonthDay::SetOffset, _val, _2)]
| date_to [_val = _1]
;
monthday_range = (date_from_with_offset >> dash >> date_to_with_offset)
[bind(&osmoh::MonthdayRange::SetStart, _val, _1),
bind(&osmoh::MonthdayRange::SetEnd, _val, _2)]
| (date_from_with_offset >> '+') [bind(&osmoh::MonthdayRange::SetStart, _val, _1),
bind(&osmoh::MonthdayRange::SetPlus, _val, true)]
| (date_right >> dash >> date_left >> '/' >> uint_)
[bind(&osmoh::MonthdayRange::SetStart, _val, _1),
bind(&osmoh::MonthdayRange::SetEnd, _val, _2),
bind(&osmoh::MonthdayRange::SetPeriod, _val, _3)]
| (date_right >> dash >> date_left) [bind(&osmoh::MonthdayRange::SetStart, _val, _1),
bind(&osmoh::MonthdayRange::SetEnd, _val, _2)]
| date_from [bind(&osmoh::MonthdayRange::SetStart, _val, _1)]
| date_left [bind(&osmoh::MonthdayRange::SetStart, _val, _1)]
;
main %= (monthday_range % ',');
BOOST_SPIRIT_DEBUG_NODE(main);
BOOST_SPIRIT_DEBUG_NODE(monthday_range);
BOOST_SPIRIT_DEBUG_NODE(day_offset);
BOOST_SPIRIT_DEBUG_NODE(date_offset);
BOOST_SPIRIT_DEBUG_NODE(date_left);
BOOST_SPIRIT_DEBUG_NODE(date_right);
BOOST_SPIRIT_DEBUG_NODE(date_from);
BOOST_SPIRIT_DEBUG_NODE(date_to);
BOOST_SPIRIT_DEBUG_NODE(date_from_with_offset);
BOOST_SPIRIT_DEBUG_NODE(date_to_with_offset);
}
};
template <typename Iterator>
//class weekday_selector : public qi::grammar<Iterator, osmoh::TWeekdayss(), space_type>
//class weekday_selector : public qi::grammar<Iterator, osmoh::THolidays(), space_type>
class weekday_selector : public qi::grammar<Iterator, osmoh::Weekdays(), space_type>
{
protected:

View file

@ -57,13 +57,13 @@ struct wdays_ : qi::symbols<char, osmoh::EWeekday>
}
} wdays;
struct month_ : qi::symbols<wchar_t, unsigned>
struct month_ : qi::symbols<wchar_t, osmoh::MonthDay::EMonth>
{
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)
(L"jan", 1_M)(L"feb", 2_M)(L"mar", 3_M)(L"apr", 4_M)(L"may", 5_M)(L"jun", 6_M)
(L"jul", 7_M)(L"aug", 8_M)(L"sep", 9_M)(L"oct", 10_M)(L"nov", 11_M)(L"dec", 12_M)
;
}
} month;

View file

@ -582,11 +582,64 @@ std::ostream & operator<<(std::ostream & ost, Weekdays const & weekday)
}
bool DateOffset::IsEmpty() const
{
return !HasOffset() && ! HasWDayOffset();
}
bool DateOffset::HasWDayOffset() const
{
return m_wday_offset != EWeekday::None;
}
bool DateOffset::HasOffset() const
{
return m_offset != 0;
}
bool DateOffset::IsWDayOffsetPositive() const
{
return m_positive;
}
EWeekday DateOffset::GetWDayOffset() const
{
return m_wday_offset;
}
int32_t DateOffset::GetOffset() const
{
return m_offset;
}
void DateOffset::SetWDayOffset(EWeekday const wday)
{
m_wday_offset = wday;
}
void DateOffset::SetOffset(int32_t const offset)
{
m_offset = offset;
}
void DateOffset::SetWDayOffsetPositive(bool const on)
{
m_positive = on;
}
std::ostream operator<<(std::ostream & ost, DateOffset const & dateOffset);
bool MonthDay::IsEmpty() const
{
return !HasYear() && !HasMonth() && !HasDayNum();
}
bool MonthDay::IsVariable() const
{
return m_variable_date != EVariableDate::None;
}
bool MonthDay::HasYear() const
{
return m_year != 0;
@ -602,19 +655,9 @@ bool MonthDay::HasDayNum() const
return m_daynum != 0;
}
bool MonthDay::HasWDayOffset() const
{
return m_offset.m_wday_offset != EWeekday::None;
}
bool MonthDay::IsWDayOffsetPositive() const
{
return m_offset.m_positive;
}
bool MonthDay::HasOffset() const
{
return m_offset.m_offset != 0;
return !m_offset.IsEmpty();
}
MonthDay::TYear MonthDay::GetYear() const
@ -632,14 +675,14 @@ MonthDay::TDayNum MonthDay::GetDayNum() const
return m_daynum;
}
EWeekday MonthDay::GetWDayOffset() const
DateOffset const & MonthDay::GetOffset() const
{
return m_offset.m_wday_offset;
return m_offset;
}
int32_t MonthDay::GetOffset() const
MonthDay::EVariableDate MonthDay::GetVariableDate() const
{
return m_offset.m_offset;
return m_variable_date;
}
void MonthDay::SetYear(TYear const year)
@ -657,22 +700,16 @@ void MonthDay::SetDayNum(TDayNum const daynum)
m_daynum = daynum;
}
void MonthDay::SetWDayOffset(EWeekday const wday)
void MonthDay::SetOffset(DateOffset const & offset)
{
m_offset.m_wday_offset = wday;
m_offset = offset;
}
void MonthDay::SetWDayOffsetPositive(bool const on)
void MonthDay::SetVariableDate(EVariableDate const date)
{
m_offset.m_positive = on;
m_variable_date = date;
}
void MonthDay::SetOffset(uint32_t const offset)
{
m_offset.m_offset = offset;
}
std::ostream & operator<<(std::ostream & ost, MonthDay::DateOffset const dateOffset);
std::ostream & operator<<(std::ostream & ost, MonthDay const md);

View file

@ -290,6 +290,30 @@ class Weekdays // Correspond to weekday_selector in osm opening hours
std::ostream & operator<<(std::ostream & ost, Weekdays const & weekday);
class DateOffset
{
public:
bool IsEmpty() const;
bool HasWDayOffset() const;
bool HasOffset() const;
bool IsWDayOffsetPositive() const;
EWeekday GetWDayOffset() const;
int32_t GetOffset() const;
void SetWDayOffset(EWeekday const wday);
void SetOffset(int32_t const offset);
void SetWDayOffsetPositive(bool const on);
private:
EWeekday m_wday_offset{EWeekday::None};
bool m_positive{true};
int32_t m_offset{};
};
std::ostream operator<<(std::ostream & ost, DateOffset const & dateOffset);
class MonthDay
{
public:
@ -316,13 +340,6 @@ class MonthDay
Easter
};
struct DateOffset
{
EWeekday m_wday_offset{EWeekday::None};
bool m_positive{true};
int32_t m_offset{};
};
using TYear = uint8_t;
using TDayNum = uint8_t;
@ -333,34 +350,37 @@ class MonthDay
bool HasYear() const;
bool HasMonth() const;
bool HasDayNum() const;
bool HasWDayOffset() const;
bool IsWDayOffsetPositive() const;
bool HasOffset() const;
TYear GetYear() const;
EMonth GetMonth() const;
TDayNum GetDayNum() const;
EWeekday GetWDayOffset() const;
int32_t GetOffset() const;
DateOffset const & GetOffset() const;
EVariableDate GetVariableDate() const;
void SetYear(TYear const year);
void SetMonth(EMonth const month);
void SetDayNum(TDayNum const daynum);
void SetWDayOffset(EWeekday const wday);
void SetWDayOffsetPositive(bool const on);
void SetOffset(uint32_t const offset);
void SetOffset(DateOffset const & offset);
void SetVariableDate(EVariableDate const date);
private:
TYear m_year{};
EMonth m_month{EMonth::None};
TDayNum m_daynum{};
EVariableDate m_variable_date{EVariableDate::None};
DateOffset m_offset{};
};
std::ostream & operator<<(std::ostream & ost, MonthDay::DateOffset const dateOffset);
inline constexpr MonthDay::EMonth operator ""_M(unsigned long long month)
{
using TMonth = decltype(month);
return ((month <= static_cast<TMonth>(MonthDay::EMonth::None) ||
month > static_cast<TMonth>(MonthDay::EMonth::Dec))
? MonthDay::EMonth::None
: static_cast<osmoh::MonthDay::EMonth>(month));
}
std::ostream & operator<<(std::ostream & ost, MonthDay const md);
class MonthdayRange