summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Lormeau <blormeau@outlook.com>2020-09-27 12:20:08 +0200
committerAndreas Kling <kling@serenityos.org>2020-09-27 21:15:25 +0200
commite4da2875c5c5aee3722e25749cc7904e5d108b3b (patch)
treeb4bde93d2c3957334a68127ed043456e91bd394c
parenteef794b8c645ea08fae3a9818c3a45ac5a4bccb4 (diff)
downloadserenity-e4da2875c5c5aee3722e25749cc7904e5d108b3b.zip
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.
-rw-r--r--AK/GenericLexer.cpp47
-rw-r--r--AK/GenericLexer.h70
2 files changed, 61 insertions, 56 deletions
diff --git a/AK/GenericLexer.cpp b/AK/GenericLexer.cpp
index cb116bb517..fe47fa6172 100644
--- a/AK/GenericLexer.cpp
+++ b/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)
{
diff --git a/AK/GenericLexer.h b/AK/GenericLexer.h
index 7800474ac4..ab1778c333 100644
--- a/AK/GenericLexer.h
+++ b/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;