Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance date parser #3797

Merged
merged 9 commits into from
Jan 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/common/time/parser/DatetimeReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,19 @@ class DatetimeReader {
}

StatusOr<DateTime> readDatetime(std::string input) {
input = kDatetimePrefix + input;
return read(std::move(input));
}

StatusOr<Date> readDate(std::string input) {
input = kDatePrefix + input;
auto result = read(std::move(input));
NG_RETURN_IF_ERROR(result);
return result.value().date();
}

StatusOr<Time> readTime(std::string input) {
input = kTimePrefix + input;
auto result = read(std::move(input));
NG_RETURN_IF_ERROR(result);
return result.value().time();
Expand All @@ -60,6 +63,10 @@ class DatetimeReader {
DatetimeParser parser_;
std::string error_;
DateTime *dt_{nullptr};

inline static const std::string kDatetimePrefix = "DATETIME__";
inline static const std::string kDatePrefix = "DATE__";
inline static const std::string kTimePrefix = "TIME__";
};

} // namespace time
Expand Down
56 changes: 32 additions & 24 deletions src/common/time/parser/datetime_parser.yy
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ enum class Type {
%token KW_TIME_ID

/* symbols */
%token TIME_DELIMITER SPACE POSITIVE NEGATIVE
%token TIME_DELIMITER SPACE POSITIVE NEGATIVE KW_DATETIME KW_DATE KW_TIME

/* token type specification */
%token <intVal> INTEGER
Expand All @@ -78,34 +78,26 @@ enum class Type {
%%

datetime
: date date_time_delimiter time opt_time_zone {
if (outputType != nebula::time::Type::kDateTime) {
delete $1;
delete $3;
throw DatetimeParser::syntax_error(@1, "Mismatched date time type.");
}
$$ = new DateTime(TimeConversion::dateTimeShift(DateTime(*$1, *$3), -$4));
: KW_DATETIME date date_time_delimiter time opt_time_zone {
$$ = new DateTime(TimeConversion::dateTimeShift(DateTime(*$2, *$4), -$5));
*output = $$;
delete $1;
delete $3;
delete $2;
delete $4;
}
| date {
if (outputType != nebula::time::Type::kDate) {
delete $1;
throw DatetimeParser::syntax_error(@1, "Mismatched date time type.");
}
$$ = new DateTime(*$1);
| KW_DATETIME date {
$$ = new DateTime(*$2);
*output = $$;
delete $1;
delete $2;
}
| time opt_time_zone {
if (outputType != nebula::time::Type::kTime) {
delete $1;
throw DatetimeParser::syntax_error(@1, "Mismatched date time type.");
}
$$ = new DateTime(TimeConversion::dateTimeShift(DateTime(1970, 1, 1, $1->hour, $1->minute, $1->sec, $1->microsec), -$2));
| KW_DATE date {
$$ = new DateTime(*$2);
*output = $$;
delete $1;
delete $2;
}
| KW_TIME time opt_time_zone {
$$ = new DateTime(TimeConversion::dateTimeShift(DateTime(1970, 1, 1, $2->hour, $2->minute, $2->sec, $2->microsec), -$3));
*output = $$;
delete $2;
}
;

Expand All @@ -131,6 +123,14 @@ date
throw DatetimeParser::syntax_error(@1, result.toString());
}
}
| INTEGER {
$$ = new nebula::Date($1, 1, 1);
auto result = nebula::time::TimeUtils::validateDate(*$$);
if (!result.ok()) {
delete $$;
throw DatetimeParser::syntax_error(@1, result.toString());
}
}
;

time
Expand Down Expand Up @@ -160,6 +160,14 @@ time
throw DatetimeParser::syntax_error(@1, result.toString());
}
}
| INTEGER {
$$ = new nebula::Time($1, 0, 0, 0);
auto result = nebula::time::TimeUtils::validateTime(*$$);
if (!result.ok()) {
delete $$;
throw DatetimeParser::syntax_error(@1, result.toString());
}
}
;

opt_time_zone
Expand Down
4 changes: 4 additions & 0 deletions src/common/time/parser/datetime_scanner.lex
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ R_BRACKET "]"
"+" { return TokenType::POSITIVE; }
"-" { return TokenType::NEGATIVE; }

"DATETIME__" { return TokenType::KW_DATETIME; }
"DATE__" { return TokenType::KW_DATE; }
"TIME__" { return TokenType::KW_TIME; }


{DEC}+ {
try {
Expand Down
95 changes: 67 additions & 28 deletions src/common/time/parser/test/DateTimeParserTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,25 @@ TEST(DatetimeReader, DateTime) {
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::DateTime(2019, 1, 1, 22, 22, 3, 233300), result.value());
}
// TODO
// lack month
// {
// auto parser = time::DatetimeReader::makeDateTimeReader();
// auto result = parser.readDatetime("2019T22:22:3.2333");
// ASSERT_TRUE(result.ok()) << result.status();
// EXPECT_EQ(nebula::DateTime(2019, 1, 1, 22, 22, 3, 233300), result.value());
// }
{
auto parser = time::DatetimeReader::makeDateTimeReader();
auto result = parser.readDatetime("2019T22:22:3.2333");
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::DateTime(2019, 1, 1, 22, 22, 3, 233300), result.value());
}
{
auto parser = time::DatetimeReader::makeDateTimeReader();
auto result = parser.readDatetime("2019T22:22");
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::DateTime(2019, 1, 1, 22, 22, 0, 0), result.value());
}
{
auto parser = time::DatetimeReader::makeDateTimeReader();
auto result = parser.readDatetime("2019T22");
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::DateTime(2019, 1, 1, 22, 0, 0, 0), result.value());
}
// lack us
{
auto parser = time::DatetimeReader::makeDateTimeReader();
Expand All @@ -54,14 +65,32 @@ TEST(DatetimeReader, DateTime) {
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::DateTime(2019, 1, 1, 22, 22, 0, 0), result.value());
}
// TODO
// lack minute
// {
// auto parser = time::DatetimeReader::makeDateTimeReader();
// auto result = parser.readDatetime("2019-1T22");
// ASSERT_TRUE(result.ok()) << result.status();
// EXPECT_EQ(nebula::DateTime(2019, 1, 1, 22, 0, 0, 0), result.value());
// }
{
auto parser = time::DatetimeReader::makeDateTimeReader();
auto result = parser.readDatetime("2019-1T22");
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::DateTime(2019, 1, 1, 22, 0, 0, 0), result.value());
}
// datetime just include date
{
auto parser = time::DatetimeReader::makeDateTimeReader();
auto result = parser.readDatetime("2019-1-1");
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::DateTime(2019, 1, 1, 0, 0, 0, 0), result.value());
}
{
auto parser = time::DatetimeReader::makeDateTimeReader();
auto result = parser.readDatetime("2019-1");
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::DateTime(2019, 1, 1, 0, 0, 0, 0), result.value());
}
{
auto parser = time::DatetimeReader::makeDateTimeReader();
auto result = parser.readDatetime("2019");
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::DateTime(2019, 1, 1, 0, 0, 0, 0), result.value());
}
}

TEST(DatetimeReader, DateTimeFailed) {
Expand Down Expand Up @@ -137,14 +166,20 @@ TEST(DatetimeReader, Date) {
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::Date(2019, 1, 1), result.value());
}
// TODO
// lack month and day
{
auto parser = time::DatetimeReader::makeDateReader();
auto result = parser.readDate("2019");
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::Date(2019, 1, 1), result.value());
}
// lack month
// {
// auto parser = time::DatetimeReader::makeDateReader();
// auto result = parser.readDate("2019");
// ASSERT_TRUE(result.ok()) << result.status();
// EXPECT_EQ(nebula::Date(2019, 1, 1), result.value());
// }
{
auto parser = time::DatetimeReader::makeDateReader();
auto result = parser.readDate("2019");
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::Date(2019, 1, 1), result.value());
}
}

TEST(DatetimeReader, DateFailed) {
Expand Down Expand Up @@ -182,6 +217,11 @@ TEST(DatetimeReader, DateFailed) {
auto result = parser.readDate("2019-01-");
EXPECT_FALSE(result.ok()) << result.value();
}
{
auto parser = time::DatetimeReader::makeDateReader();
auto result = parser.readDate("2019-");
EXPECT_FALSE(result.ok()) << result.value();
}
// not exits prefix
{
auto parser = time::DatetimeReader::makeDateReader();
Expand Down Expand Up @@ -224,14 +264,13 @@ TEST(DatetimeReader, Time) {
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::Time(22, 22, 0, 0), result.value());
}
// TODO
// lack minute
// {
// auto parser = time::DatetimeReader::makeTimeReader();
// auto result = parser.readTime("22");
// ASSERT_TRUE(result.ok()) << result.status();
// EXPECT_EQ(nebula::Time(22, 0, 0, 0), result.value());
// }
{
auto parser = time::DatetimeReader::makeTimeReader();
auto result = parser.readTime("22");
ASSERT_TRUE(result.ok()) << result.status();
EXPECT_EQ(nebula::Time(22, 0, 0, 0), result.value());
}
}

TEST(DatetimeReader, TimeFailed) {
Expand Down