Jelajahi Sumber

AK: Add a DateTimeLexer

This is an AK::GenericLexer that exposes helper methods for parsing
date and time related literals (years, months, days, hours, minutes,
seconds, fractional seconds & more)
Idan Horowitz 4 tahun lalu
induk
melakukan
141c46feda

+ 146 - 0
AK/DateTimeLexer.h

@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/CharacterTypes.h>
+#include <AK/GenericLexer.h>
+#include <AK/Optional.h>
+
+namespace AK {
+
+class DateTimeLexer : public GenericLexer {
+public:
+    constexpr explicit DateTimeLexer(const StringView& input)
+        : GenericLexer(input)
+    {
+    }
+
+    Optional<StringView> consume_year()
+    {
+        if (tell_remaining() < 4)
+            return {};
+
+        for (auto i = 0; i < 4; ++i) {
+            if (!is_ascii_digit(peek(i)))
+                return {};
+        }
+        return consume(4);
+    }
+
+    Optional<StringView> consume_month()
+    {
+        if (tell_remaining() < 2)
+            return {};
+
+        auto tens = peek();
+        if (tens != '0' && tens != '1')
+            return {};
+
+        auto ones = peek(1);
+        if (!is_ascii_digit(ones))
+            return {};
+
+        if (tens == '0') { // 01, 02, 03, 04, 05, 06, 07, 08, 09
+            if (ones == '0')
+                return {};
+        } else if (ones > '2') { // 10, 11, 12
+            return {};
+        }
+
+        return consume(2);
+    }
+
+    Optional<StringView> consume_day()
+    {
+        if (tell_remaining() < 2)
+            return {};
+
+        auto tens = peek();
+        if (tens < '0' || tens > '3')
+            return {};
+
+        auto ones = peek(1);
+        if (!is_ascii_digit(ones))
+            return {};
+
+        if (tens == '0') { // 01, 02, 03, 04, 05, 06, 07, 08, 09
+            if (ones == '0')
+                return {};
+        } else if (tens == '3') { // 30, 31
+            if (ones != '0' && ones != '1')
+                return {};
+        } else if (!is_ascii_digit(ones)) { // 10 - 29
+            return {};
+        }
+
+        return consume(2);
+    }
+
+    Optional<StringView> consume_sign()
+    {
+        if (!tell_remaining())
+            return {};
+
+        if (next_is("\xE2\x88\x92"sv))
+            return consume(3);
+        else if (next_is('-') || next_is('+'))
+            return consume(1);
+        else
+            return {};
+    };
+
+    Optional<StringView> consume_hours()
+    {
+        if (tell_remaining() < 2)
+            return {};
+
+        char tens = peek();
+        if (tens != '0' && tens != '1' && tens != '2')
+            return {};
+
+        char ones = peek(1);
+        if (!is_ascii_digit(ones) || (tens == '2' && ones > '3'))
+            return {};
+
+        return consume(2);
+    }
+
+    Optional<StringView> consume_minutes_or_seconds()
+    {
+        if (tell_remaining() < 2)
+            return {};
+
+        char tens = peek();
+        if (tens < '0' || tens > '5')
+            return {};
+
+        if (!is_ascii_digit(peek(1)))
+            return {};
+
+        return consume(2);
+    }
+
+    Optional<StringView> consume_fractional_seconds()
+    {
+        if (!tell_remaining())
+            return {};
+
+        auto length = min(tell_remaining(), 9);
+        for (size_t i = 0; i < length; ++i) {
+            if (is_ascii_digit(peek(i)))
+                continue;
+            length = i;
+            break;
+        }
+
+        return consume(length);
+    }
+};
+
+}
+
+using AK::DateTimeLexer;

+ 0 - 21
Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp

@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include <AK/String.h>
-#include <LibJS/Runtime/Temporal/ISO8601.h>
-
-namespace JS::Temporal {
-
-// 13.33 ISO 8601 grammar, https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar
-
-// TimeZoneNumericUTCOffset, https://tc39.es/proposal-temporal/#prod-TimeZoneNumericUTCOffset
-bool is_valid_time_zone_numeric_utc_offset(String const&)
-{
-    // TODO: Implement me :^)
-    return false;
-}
-
-}

+ 0 - 17
Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h

@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include <LibJS/Forward.h>
-
-namespace JS::Temporal {
-
-// 13.33 ISO 8601 grammar, https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar
-
-bool is_valid_time_zone_numeric_utc_offset(String const&);
-
-}