parser: revise

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2023-07-17 17:05:31 +02:00
parent f55d5636aa
commit c5f972971e
2 changed files with 69 additions and 48 deletions

View File

@ -125,11 +125,11 @@ namespace UnitTests
wcu chr_t(L't'), chr_h(L'h'), chr_i(L'i'), chr_s(L's'); wcu chr_t(L't'), chr_h(L'h'), chr_i(L'i'), chr_s(L's');
wspace_cu space; wspace_cu space;
wsequence p({ wsequence p({
make_shared_no_delete<basic_parser<wchar_t>>(&chr_t), make_shared_no_delete(&chr_t),
make_shared_no_delete<basic_parser<wchar_t>>(&chr_h), make_shared_no_delete(&chr_h),
make_shared_no_delete<basic_parser<wchar_t>>(&chr_i), make_shared_no_delete(&chr_i),
make_shared_no_delete<basic_parser<wchar_t>>(&chr_s), make_shared_no_delete(&chr_s),
make_shared_no_delete<basic_parser<wchar_t>>(&space) }); make_shared_no_delete(&space) });
Assert::IsFalse(p.match(text)); Assert::IsFalse(p.match(text));
Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive)); Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive));
Assert::AreEqual((size_t)0, p.interval.start); Assert::AreEqual((size_t)0, p.interval.start);
@ -140,10 +140,10 @@ namespace UnitTests
stdex::parser::wstring apple(L"apple"), orange(L"orange"), _this(L"this"); stdex::parser::wstring apple(L"apple"), orange(L"orange"), _this(L"this");
wspace_cu space; wspace_cu space;
wbranch p({ wbranch p({
make_shared_no_delete<basic_parser<wchar_t>>(&apple), make_shared_no_delete(&apple),
make_shared_no_delete<basic_parser<wchar_t>>(&orange), make_shared_no_delete(&orange),
make_shared_no_delete<basic_parser<wchar_t>>(&_this), make_shared_no_delete(&_this),
make_shared_no_delete<basic_parser<wchar_t>>(&space) }); make_shared_no_delete(&space) });
Assert::IsFalse(p.match(text)); Assert::IsFalse(p.match(text));
Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive)); Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive));
Assert::AreEqual((size_t)2, p.hit_offset); Assert::AreEqual((size_t)2, p.hit_offset);
@ -163,10 +163,10 @@ namespace UnitTests
{ {
wcu chr_s(L's'), chr_h(L'h'), chr_i(L'i'), chr_t(L't'); wcu chr_s(L's'), chr_h(L'h'), chr_i(L'i'), chr_t(L't');
wpermutation p({ wpermutation p({
make_shared_no_delete<basic_parser<wchar_t>>(&chr_s), make_shared_no_delete(&chr_s),
make_shared_no_delete<basic_parser<wchar_t>>(&chr_h), make_shared_no_delete(&chr_h),
make_shared_no_delete<basic_parser<wchar_t>>(&chr_i), make_shared_no_delete(&chr_i),
make_shared_no_delete<basic_parser<wchar_t>>(&chr_t) }); make_shared_no_delete(&chr_t) });
Assert::IsFalse(p.match(text)); Assert::IsFalse(p.match(text));
Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive)); Assert::IsTrue(p.match(text, 0, _countof(text), match_case_insensitive));
Assert::AreEqual((size_t)0, p.interval.start); Assert::AreEqual((size_t)0, p.interval.start);

View File

@ -30,6 +30,20 @@
#pragma warning(disable: 4100) #pragma warning(disable: 4100)
#endif #endif
#define ENUM_FLAG_OPERATOR(T,X) \
inline T operator X (const T lhs, const T rhs) { return static_cast<T>(static_cast<std::underlying_type_t<T>>(lhs) X static_cast<std::underlying_type_t<T>>(rhs)); } \
inline T operator X (const T lhs, const std::underlying_type_t<T> rhs) { return static_cast<T>(static_cast<std::underlying_type_t<T>>(lhs) X rhs); } \
inline T operator X (const std::underlying_type_t<T> lhs, const T rhs) { return static_cast<T>(lhs X static_cast<std::underlying_type_t<T>>(rhs)); } \
inline T& operator X= (T& lhs, const T rhs) { return lhs = lhs X rhs; } \
inline T& operator X= (T& lhs, const std::underlying_type_t<T> rhs) { return lhs = lhs X rhs; }
#define ENUM_FLAGS(T, type) \
enum class T : type; \
inline T operator ~ (T t) { return (T) (~static_cast<std::underlying_type_t <T>>(t)); } \
ENUM_FLAG_OPERATOR(T,|) \
ENUM_FLAG_OPERATOR(T,^) \
ENUM_FLAG_OPERATOR(T,&) \
enum class T : type
namespace stdex namespace stdex
{ {
namespace parser namespace parser
@ -2416,7 +2430,7 @@ namespace stdex
components[2].end = 0; components[2].end = 0;
components[3].start = 1; components[3].start = 1;
components[3].end = 0; components[3].end = 0;
value = 0; value.s_addr = 0;
interval.start = (interval.end = start) + 1; interval.start = (interval.end = start) + 1;
return false; return false;
} }
@ -2431,7 +2445,7 @@ namespace stdex
components[2].end = 0; components[2].end = 0;
components[3].start = 1; components[3].start = 1;
components[3].end = 0; components[3].end = 0;
value = 0; value.s_addr = 0;
basic_parser<T>::invalidate(); basic_parser<T>::invalidate();
} }
@ -2584,7 +2598,7 @@ namespace stdex
m_scope_id_separator(scope_id_separator), m_scope_id_separator(scope_id_separator),
scope_id(_scope_id) scope_id(_scope_id)
{ {
memset(value, 0, sizeof(value)); memset(&value, 0, sizeof(value));
} }
virtual bool match( virtual bool match(
@ -2595,7 +2609,7 @@ namespace stdex
{ {
assert(text || start >= end); assert(text || start >= end);
interval.end = start; interval.end = start;
memset(value, 0, sizeof(value)); memset(&value, 0, sizeof(value));
size_t i, compaction_i = (size_t)-1, compaction_start = start; size_t i, compaction_i = (size_t)-1, compaction_start = start;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
@ -2712,7 +2726,7 @@ namespace stdex
components[6].end = 0; components[6].end = 0;
components[7].start = 1; components[7].start = 1;
components[7].end = 0; components[7].end = 0;
memset(value, 0, sizeof(value)); memset(&value, 0, sizeof(value));
if (scope_id) scope_id->invalidate(); if (scope_id) scope_id->invalidate();
interval.start = (interval.end = start) + 1; interval.start = (interval.end = start) + 1;
return false; return false;
@ -2736,7 +2750,7 @@ namespace stdex
components[6].end = 0; components[6].end = 0;
components[7].start = 1; components[7].start = 1;
components[7].end = 0; components[7].end = 0;
memset(value, 0, sizeof(value)); memset(&value, 0, sizeof(value));
if (scope_id) scope_id->invalidate(); if (scope_id) scope_id->invalidate();
basic_parser<T>::invalidate(); basic_parser<T>::invalidate();
} }
@ -3982,13 +3996,10 @@ namespace stdex
using sgml_emoticon = basic_emoticon<char>; using sgml_emoticon = basic_emoticon<char>;
/// ///
/// Test for date /// Date format type
/// ///
template <class T> ENUM_FLAGS(date_format_t, int) {
class basic_date : public basic_parser<T> none = 0,
{
public:
enum class format {
dmy = 0x1, dmy = 0x1,
mdy = 0x2, mdy = 0x2,
ymd = 0x4, ymd = 0x4,
@ -3998,6 +4009,13 @@ namespace stdex
md = 0x40, md = 0x40,
}; };
///
/// Test for date
///
template <class T>
class basic_date : public basic_parser<T>
{
public:
basic_date( basic_date(
_In_ int format_mask, _In_ int format_mask,
_In_ const std::shared_ptr<basic_integer<T>>& _day, _In_ const std::shared_ptr<basic_integer<T>>& _day,
@ -4007,7 +4025,7 @@ namespace stdex
_In_ const std::shared_ptr<basic_parser<T>>& space, _In_ const std::shared_ptr<basic_parser<T>>& space,
_In_ const std::locale& locale = std::locale()) : _In_ const std::locale& locale = std::locale()) :
basic_parser<T>(locale), basic_parser<T>(locale),
format(0), format(date_format_t::none),
m_format_mask(format_mask), m_format_mask(format_mask),
day(_day), day(_day),
month(_month), month(_month),
@ -4025,7 +4043,7 @@ namespace stdex
assert(text || start >= end); assert(text || start >= end);
const int space_match_flags = flags & ~match_multiline; // Spaces in dates must never be broken in new line. const int space_match_flags = flags & ~match_multiline; // Spaces in dates must never be broken in new line.
if ((m_format_mask & format::dmy) != 0) { if ((m_format_mask & date_format_t::dmy) == date_format_t::dmy) {
if (day->match(text, start, end, flags)) { if (day->match(text, start, end, flags)) {
for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end); for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
if (m_separator->match(text, interval.end, end, flags)) { if (m_separator->match(text, interval.end, end, flags)) {
@ -4042,7 +4060,7 @@ namespace stdex
{ {
interval.start = start; interval.start = start;
interval.end = year->interval.end; interval.end = year->interval.end;
format = format::dmy; format = date_format_t::dmy;
return true; return true;
} }
} }
@ -4051,7 +4069,7 @@ namespace stdex
} }
} }
if ((m_format_mask & format::mdy) != 0) { if ((m_format_mask & date_format_t::mdy) == date_format_t::mdy) {
if (month->match(text, start, end, flags)) { if (month->match(text, start, end, flags)) {
for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end); for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
if (m_separator->match(text, interval.end, end, flags)) { if (m_separator->match(text, interval.end, end, flags)) {
@ -4068,7 +4086,7 @@ namespace stdex
{ {
interval.start = start; interval.start = start;
interval.end = year->interval.end; interval.end = year->interval.end;
format = format::mdy; format = date_format_t::mdy;
return true; return true;
} }
} }
@ -4077,7 +4095,7 @@ namespace stdex
} }
} }
if ((m_format_mask & format::ymd) != 0) { if ((m_format_mask & date_format_t::ymd) == date_format_t::ymd) {
if (year->match(text, start, end, flags)) { if (year->match(text, start, end, flags)) {
for (interval.end = year->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end); for (interval.end = year->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
if (m_separator->match(text, interval.end, end, flags)) { if (m_separator->match(text, interval.end, end, flags)) {
@ -4094,7 +4112,7 @@ namespace stdex
{ {
interval.start = start; interval.start = start;
interval.end = day->interval.end; interval.end = day->interval.end;
format = format::ymd; format = date_format_t::ymd;
return true; return true;
} }
} }
@ -4103,7 +4121,7 @@ namespace stdex
} }
} }
if ((m_format_mask & format::ym) != 0) { if ((m_format_mask & date_format_t::ym) == date_format_t::ym) {
if (year->match(text, start, end, flags)) { if (year->match(text, start, end, flags)) {
for (interval.end = year->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end); for (interval.end = year->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
if (m_separator->match(text, interval.end, end, flags)) { if (m_separator->match(text, interval.end, end, flags)) {
@ -4114,14 +4132,14 @@ namespace stdex
if (day) day->invalidate(); if (day) day->invalidate();
interval.start = start; interval.start = start;
interval.end = month->interval.end; interval.end = month->interval.end;
format = format::ym; format = date_format_t::ym;
return true; return true;
} }
} }
} }
} }
if ((m_format_mask & format::my) != 0) { if ((m_format_mask & date_format_t::my) == date_format_t::my) {
if (month->match(text, start, end, flags)) { if (month->match(text, start, end, flags)) {
for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end); for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
if (m_separator->match(text, interval.end, end, flags)) { if (m_separator->match(text, interval.end, end, flags)) {
@ -4132,14 +4150,14 @@ namespace stdex
if (day) day->invalidate(); if (day) day->invalidate();
interval.start = start; interval.start = start;
interval.end = year->interval.end; interval.end = year->interval.end;
format = format::my; format = date_format_t::my;
return true; return true;
} }
} }
} }
} }
if ((m_format_mask & format::dm) != 0) { if ((m_format_mask & date_format_t::dm) == date_format_t::dm) {
if (day->match(text, start, end, flags)) { if (day->match(text, start, end, flags)) {
for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end); for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
if (m_separator->match(text, interval.end, end, flags)) { if (m_separator->match(text, interval.end, end, flags)) {
@ -4156,14 +4174,14 @@ namespace stdex
interval.end = m_separator->interval.end; interval.end = m_separator->interval.end;
else else
interval.end = month->interval.end; interval.end = month->interval.end;
format = format::dm; format = date_format_t::dm;
return true; return true;
} }
} }
} }
} }
if ((m_format_mask & format::md) != 0) { if ((m_format_mask & date_format_t::md) == date_format_t::md) {
if (month->match(text, start, end, flags)) { if (month->match(text, start, end, flags)) {
for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end); for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
if (m_separator->match(text, interval.end, end, flags)) { if (m_separator->match(text, interval.end, end, flags)) {
@ -4180,7 +4198,7 @@ namespace stdex
interval.end = m_separator->interval.end; interval.end = m_separator->interval.end;
else else
interval.end = day->interval.end; interval.end = day->interval.end;
format = format::md; format = date_format_t::md;
return true; return true;
} }
} }
@ -4190,7 +4208,7 @@ namespace stdex
if (day) day->invalidate(); if (day) day->invalidate();
if (month) month->invalidate(); if (month) month->invalidate();
if (year) year->invalidate(); if (year) year->invalidate();
format = 0; format = date_format_t::none;
interval.start = (interval.end = start) + 1; interval.start = (interval.end = start) + 1;
return false; return false;
} }
@ -4200,7 +4218,7 @@ namespace stdex
if (day) day->invalidate(); if (day) day->invalidate();
if (month) month->invalidate(); if (month) month->invalidate();
if (year) year->invalidate(); if (year) year->invalidate();
format = 0; format = date_format_t::none;
basic_parser<T>::invalidate(); basic_parser<T>::invalidate();
} }
@ -4238,7 +4256,7 @@ namespace stdex
} }
public: public:
format format; date_format_t format;
std::shared_ptr<basic_integer<T>> day; std::shared_ptr<basic_integer<T>> day;
std::shared_ptr<basic_integer<T>> month; std::shared_ptr<basic_integer<T>> month;
std::shared_ptr<basic_integer<T>> year; std::shared_ptr<basic_integer<T>> year;
@ -4553,7 +4571,7 @@ namespace stdex
m_lparenthesis->match(text, interval.end, end, flags)) m_lparenthesis->match(text, interval.end, end, flags))
{ {
// Left parenthesis // Left parenthesis
value.Prilepi(text + m_lparenthesis->interval.start, m_lparenthesis->interval.size()); value.append(text + m_lparenthesis->interval.start, m_lparenthesis->interval.size());
interval.end = m_lparenthesis->interval.end; interval.end = m_lparenthesis->interval.end;
in_parentheses = true; in_parentheses = true;
after_digit = false; after_digit = false;
@ -6552,6 +6570,9 @@ namespace stdex
} }
} }
#undef ENUM_FLAG_OPERATOR
#undef ENUM_FLAGS
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
#endif #endif