Ver Fonte

AK: Use templates instead of Function for Conditions in the GenericLexer

Since commit 1ec59f28cea56f1afced0994127e2df62300e618 turns the ctype macros
into functions we can now feed them directly to a GenericLexer! This will lead to
removing the ctype adapters that were kind-of excessive boilerplate, but needed as
the Kernel doesn't compile with the LibC.
Benoit Lormeau há 4 anos atrás
pai
commit
e4da2875c5
2 ficheiros alterados com 61 adições e 56 exclusões
  1. 0 47
      AK/GenericLexer.cpp
  2. 61 9
      AK/GenericLexer.h

+ 0 - 47
AK/GenericLexer.cpp

@@ -75,12 +75,6 @@ bool GenericLexer::next_is(const char* expected) const
     return true;
 }
 
-// Tests the next character against a Condition
-bool GenericLexer::next_is(Condition condition) const
-{
-    return condition(peek());
-}
-
 // Consume a character and advance the parser index
 char GenericLexer::consume()
 {
@@ -154,19 +148,6 @@ StringView GenericLexer::consume_line()
     return m_input.substring_view(start, length);
 }
 
-// Consume and return characters while `condition` returns true
-StringView GenericLexer::consume_while(Condition condition)
-{
-    size_t start = m_index;
-    while (!is_eof() && condition(peek()))
-        m_index++;
-    size_t length = m_index - start;
-
-    if (length == 0)
-        return {};
-    return m_input.substring_view(start, length);
-}
-
 // Consume and return characters until `stop` is peek'd
 // The `stop` character is ignored, as it is user-defined
 StringView GenericLexer::consume_until(char stop)
@@ -199,19 +180,6 @@ StringView GenericLexer::consume_until(const char* stop)
     return m_input.substring_view(start, length);
 }
 
-// Consume and return characters until `condition` return true
-StringView GenericLexer::consume_until(Condition condition)
-{
-    size_t start = m_index;
-    while (!is_eof() && !condition(peek()))
-        m_index++;
-    size_t length = m_index - start;
-
-    if (length == 0)
-        return {};
-    return m_input.substring_view(start, length);
-}
-
 /*
  * Consume a string surrounded by single or double quotes. The returned
  * StringView does not include the quotes. An escape character can be provided
@@ -276,13 +244,6 @@ void GenericLexer::ignore(size_t count)
     m_index += count;
 }
 
-// Ignore characters while `condition` returns true
-void GenericLexer::ignore_while(Condition condition)
-{
-    while (!is_eof() && condition(peek()))
-        m_index++;
-}
-
 // Ignore characters until `stop` is peek'd
 // The `stop` character is ignored as it is user-defined
 void GenericLexer::ignore_until(char stop)
@@ -303,14 +264,6 @@ void GenericLexer::ignore_until(const char* stop)
     ignore(__builtin_strlen(stop));
 }
 
-// Ignore characters until `condition` return true
-// We don't skip the stop character as it may not be a unique value
-void GenericLexer::ignore_until(Condition condition)
-{
-    while (!is_eof() && !condition(peek()))
-        m_index++;
-}
-
 // CType adapters
 bool is_alpha(char c)
 {

+ 61 - 9
AK/GenericLexer.h

@@ -26,7 +26,6 @@
 
 #pragma once
 
-#include <AK/Function.h>
 #include <AK/String.h>
 #include <AK/StringView.h>
 
@@ -37,9 +36,6 @@ public:
     explicit GenericLexer(const StringView& input);
     virtual ~GenericLexer();
 
-    // A lambda/function can be used to match characters as the user pleases
-    using Condition = Function<bool(char)>;
-
     size_t tell() const { return m_index; }
     size_t tell_remaining() const { return m_input.length() - m_index; }
 
@@ -52,7 +48,6 @@ public:
     bool next_is(char) const;
     bool next_is(StringView) const;
     bool next_is(const char*) const;
-    bool next_is(Condition) const;
 
     char consume();
     bool consume_specific(char);
@@ -61,18 +56,75 @@ public:
     StringView consume(size_t count);
     StringView consume_all();
     StringView consume_line();
-    StringView consume_while(Condition);
     StringView consume_until(char);
     StringView consume_until(const char*);
-    StringView consume_until(Condition);
     StringView consume_quoted_string(char escape_char = 0);
     String consume_and_unescape_string(char escape_char = '\\');
 
     void ignore(size_t count = 1);
-    void ignore_while(Condition);
     void ignore_until(char);
     void ignore_until(const char*);
-    void ignore_until(Condition);
+
+    /*
+     * Conditions are used to match arbitrary characters. You can use lambdas,
+     * ctype functions, or is_any_of() and its derivatives (see below).
+     * A few examples:
+     *   - `if (lexer.next_is(isdigit))`
+     *   - `auto name = lexer.consume_while([](char c) { return isalnum(c) || c == '_'; });`
+     *   - `lexer.ignore_until(is_any_of("<^>"));`
+     */
+
+    // Test the next character against a Condition
+    template<typename C>
+    bool next_is(C condition) const
+    {
+        return condition(peek());
+    }
+
+    // Consume and return characters while `condition` returns true
+    template<typename C>
+    StringView consume_while(C condition)
+    {
+        size_t start = m_index;
+        while (!is_eof() && condition(peek()))
+            m_index++;
+        size_t length = m_index - start;
+
+        if (length == 0)
+            return {};
+        return m_input.substring_view(start, length);
+    }
+
+    // Consume and return characters until `condition` return true
+    template<typename C>
+    StringView consume_until(C condition)
+    {
+        size_t start = m_index;
+        while (!is_eof() && !condition(peek()))
+            m_index++;
+        size_t length = m_index - start;
+
+        if (length == 0)
+            return {};
+        return m_input.substring_view(start, length);
+    }
+
+    // Ignore characters while `condition` returns true
+    template<typename C>
+    void ignore_while(C condition)
+    {
+        while (!is_eof() && condition(peek()))
+            m_index++;
+    }
+
+    // Ignore characters until `condition` return true
+    // We don't skip the stop character as it may not be a unique value
+    template<typename C>
+    void ignore_until(C condition)
+    {
+        while (!is_eof() && !condition(peek()))
+            m_index++;
+    }
 
 protected:
     StringView m_input;