Ver código fonte

LibWeb: Use GenericLexer in WrapperGenerator

Nico Weber 4 anos atrás
pai
commit
064159d215

+ 17 - 2
AK/GenericLexer.cpp

@@ -56,6 +56,15 @@ bool GenericLexer::next_is(char expected) const
     return peek() == expected;
     return peek() == expected;
 }
 }
 
 
+// Tests if the `expected` string comes next in the input
+bool GenericLexer::next_is(StringView expected) const
+{
+    for (size_t i = 0; i < expected.length(); ++i)
+        if (peek(i) != expected[i])
+            return false;
+    return true;
+}
+
 // Tests if the `expected` string comes next in the input
 // Tests if the `expected` string comes next in the input
 bool GenericLexer::next_is(const char* expected) const
 bool GenericLexer::next_is(const char* expected) const
 {
 {
@@ -89,15 +98,21 @@ bool GenericLexer::consume_specific(char specific)
 }
 }
 
 
 // Consume the given string if it is next in the input
 // Consume the given string if it is next in the input
-bool GenericLexer::consume_specific(const char* str)
+bool GenericLexer::consume_specific(StringView str)
 {
 {
     if (!next_is(str))
     if (!next_is(str))
         return false;
         return false;
 
 
-    ignore(__builtin_strlen(str));
+    ignore(str.length());
     return true;
     return true;
 }
 }
 
 
+// Consume the given string if it is next in the input
+bool GenericLexer::consume_specific(const char* str)
+{
+    return consume_specific(StringView(str));
+}
+
 // Consume a number of characters
 // Consume a number of characters
 StringView GenericLexer::consume(size_t count)
 StringView GenericLexer::consume(size_t count)
 {
 {

+ 10 - 8
AK/GenericLexer.h

@@ -45,27 +45,29 @@ public:
 
 
     char peek(size_t offset = 0) const;
     char peek(size_t offset = 0) const;
 
 
-    bool next_is(char expected) const;
-    bool next_is(const char* expected) const;
+    bool next_is(char) const;
+    bool next_is(StringView) const;
+    bool next_is(const char*) const;
     bool next_is(Condition) const;
     bool next_is(Condition) const;
 
 
     char consume();
     char consume();
-    bool consume_specific(char specific);
-    bool consume_specific(const char* str);
+    bool consume_specific(char);
+    bool consume_specific(StringView);
+    bool consume_specific(const char*);
     StringView consume(size_t count);
     StringView consume(size_t count);
     StringView consume_all();
     StringView consume_all();
     StringView consume_line();
     StringView consume_line();
     StringView consume_while(Condition);
     StringView consume_while(Condition);
-    StringView consume_until(char stop);
-    StringView consume_until(const char* stop);
+    StringView consume_until(char);
+    StringView consume_until(const char*);
     StringView consume_until(Condition);
     StringView consume_until(Condition);
     // FIXME: provide an escape character
     // FIXME: provide an escape character
     StringView consume_quoted_string();
     StringView consume_quoted_string();
 
 
     void ignore(size_t count = 1);
     void ignore(size_t count = 1);
     void ignore_while(Condition);
     void ignore_while(Condition);
-    void ignore_until(char stop);
-    void ignore_until(const char* stop);
+    void ignore_until(char);
+    void ignore_until(const char*);
     void ignore_until(Condition);
     void ignore_until(Condition);
 
 
 protected:
 protected:

+ 43 - 82
Libraries/LibWeb/CodeGenerators/WrapperGenerator.cpp

@@ -25,6 +25,7 @@
  */
  */
 
 
 #include <AK/ByteBuffer.h>
 #include <AK/ByteBuffer.h>
+#include <AK/GenericLexer.h>
 #include <AK/HashMap.h>
 #include <AK/HashMap.h>
 #include <AK/LexicalPath.h>
 #include <AK/LexicalPath.h>
 #include <AK/StringBuilder.h>
 #include <AK/StringBuilder.h>
@@ -120,101 +121,59 @@ static OwnPtr<Interface> parse_interface(const StringView& input)
 {
 {
     auto interface = make<Interface>();
     auto interface = make<Interface>();
 
 
-    size_t index = 0;
+    GenericLexer lexer(input);
 
 
-    auto peek = [&](size_t offset = 0) -> char {
-        if (index + offset > input.length())
-            return 0;
-        return input[index + offset];
-    };
-
-    auto consume = [&] {
-        return input[index++];
-    };
-
-    auto consume_if = [&](auto ch) {
-        if (peek() == ch) {
-            consume();
-            return true;
-        }
-        return false;
-    };
-
-    auto consume_specific = [&](char ch) {
-        auto consumed = consume();
+    auto assert_specific = [&](char ch) {
+        auto consumed = lexer.consume();
         if (consumed != ch) {
         if (consumed != ch) {
-            dbg() << "Expected '" << ch << "' at offset " << index << " but got '" << consumed << "'";
+            dbg() << "Expected '" << ch << "' at offset " << lexer.tell() << " but got '" << consumed << "'";
             ASSERT_NOT_REACHED();
             ASSERT_NOT_REACHED();
         }
         }
     };
     };
 
 
     auto consume_whitespace = [&] {
     auto consume_whitespace = [&] {
-        while (isspace(peek()))
-            consume();
+        lexer.consume_while([](char ch) { return isspace(ch); });
     };
     };
 
 
-    auto consume_string = [&](const StringView& string) {
-        for (size_t i = 0; i < string.length(); ++i) {
-            ASSERT(consume() == string[i]);
-        }
+    auto assert_string = [&](const StringView& expected) {
+        bool saw_expected = lexer.consume_specific(expected);
+        ASSERT(saw_expected);
     };
     };
 
 
-    auto next_is = [&](const StringView& string) {
-        for (size_t i = 0; i < string.length(); ++i) {
-            if (peek(i) != string[i])
-                return false;
-        }
-        return true;
-    };
-
-    auto consume_while = [&](auto condition) {
-        StringBuilder builder;
-        while (index < input.length() && condition(peek())) {
-            builder.append(consume());
-        }
-        return builder.to_string();
-    };
-
-    consume_string("interface");
+    assert_string("interface");
     consume_whitespace();
     consume_whitespace();
-    interface->name = consume_while([](auto ch) { return !isspace(ch); });
+    interface->name = lexer.consume_until([](auto ch) { return isspace(ch); });
     consume_whitespace();
     consume_whitespace();
-    if (consume_if(':')) {
+    if (lexer.consume_specific(':')) {
         consume_whitespace();
         consume_whitespace();
-        interface->parent_name = consume_while([](auto ch) { return !isspace(ch); });
+        interface->parent_name = lexer.consume_until([](auto ch) { return isspace(ch); });
         consume_whitespace();
         consume_whitespace();
     }
     }
-    consume_specific('{');
+    assert_specific('{');
 
 
     auto parse_type = [&] {
     auto parse_type = [&] {
-        auto name = consume_while([](auto ch) { return !isspace(ch) && ch != '?'; });
-        auto nullable = peek() == '?';
-        if (nullable)
-            consume_specific('?');
+        auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == '?'; });
+        auto nullable = lexer.consume_specific('?');
         return Type { name, nullable };
         return Type { name, nullable };
     };
     };
 
 
     auto parse_attribute = [&](HashMap<String, String>& extended_attributes) {
     auto parse_attribute = [&](HashMap<String, String>& extended_attributes) {
-        bool readonly = false;
-        bool unsigned_ = false;
-        if (next_is("readonly")) {
-            consume_string("readonly");
-            readonly = true;
+        bool readonly = lexer.consume_specific("readonly");
+        if (readonly)
             consume_whitespace();
             consume_whitespace();
-        }
-        if (next_is("attribute")) {
-            consume_string("attribute");
+
+        if (lexer.consume_specific("attribute"))
             consume_whitespace();
             consume_whitespace();
-        }
-        if (next_is("unsigned")) {
-            consume_string("unsigned");
-            unsigned_ = true;
+
+        bool unsigned_ = lexer.consume_specific("unsigned");
+        if (unsigned_)
             consume_whitespace();
             consume_whitespace();
-        }
+
         auto type = parse_type();
         auto type = parse_type();
         consume_whitespace();
         consume_whitespace();
-        auto name = consume_while([](auto ch) { return !isspace(ch) && ch != ';'; });
-        consume_specific(';');
+        auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == ';'; });
+        consume_whitespace();
+        assert_specific(';');
         Attribute attribute;
         Attribute attribute;
         attribute.readonly = readonly;
         attribute.readonly = readonly;
         attribute.unsigned_ = unsigned_;
         attribute.unsigned_ = unsigned_;
@@ -229,25 +188,27 @@ static OwnPtr<Interface> parse_interface(const StringView& input)
     auto parse_function = [&](HashMap<String, String>& extended_attributes) {
     auto parse_function = [&](HashMap<String, String>& extended_attributes) {
         auto return_type = parse_type();
         auto return_type = parse_type();
         consume_whitespace();
         consume_whitespace();
-        auto name = consume_while([](auto ch) { return !isspace(ch) && ch != '('; });
-        consume_specific('(');
+        auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == '('; });
+        consume_whitespace();
+        assert_specific('(');
 
 
         Vector<Parameter> parameters;
         Vector<Parameter> parameters;
 
 
         for (;;) {
         for (;;) {
-            if (consume_if(')'))
+            if (lexer.consume_specific(')'))
                 break;
                 break;
             auto type = parse_type();
             auto type = parse_type();
             consume_whitespace();
             consume_whitespace();
-            auto name = consume_while([](auto ch) { return !isspace(ch) && ch != ',' && ch != ')'; });
+            auto name = lexer.consume_until([](auto ch) { return isspace(ch) || ch == ',' || ch == ')'; });
             parameters.append({ move(type), move(name) });
             parameters.append({ move(type), move(name) });
-            if (consume_if(')'))
+            if (lexer.consume_specific(')'))
                 break;
                 break;
-            consume_specific(',');
+            assert_specific(',');
             consume_whitespace();
             consume_whitespace();
         }
         }
 
 
-        consume_specific(';');
+        consume_whitespace();
+        assert_specific(';');
 
 
         interface->functions.append(Function { return_type, name, move(parameters), move(extended_attributes) });
         interface->functions.append(Function { return_type, name, move(parameters), move(extended_attributes) });
     };
     };
@@ -256,11 +217,11 @@ static OwnPtr<Interface> parse_interface(const StringView& input)
         HashMap<String, String> extended_attributes;
         HashMap<String, String> extended_attributes;
         for (;;) {
         for (;;) {
             consume_whitespace();
             consume_whitespace();
-            if (consume_if(']'))
+            if (lexer.consume_specific(']'))
                 break;
                 break;
-            auto name = consume_while([](auto ch) { return ch != ']' && ch != '=' && ch != ','; });
-            if (consume_if('=')) {
-                auto value = consume_while([](auto ch) { return ch != ']' && ch != ','; });
+            auto name = lexer.consume_until([](auto ch) { return ch == ']' || ch == '=' || ch == ','; });
+            if (lexer.consume_specific('=')) {
+                auto value = lexer.consume_until([](auto ch) { return ch == ']' || ch == ','; });
                 extended_attributes.set(name, value);
                 extended_attributes.set(name, value);
             } else {
             } else {
                 extended_attributes.set(name, {});
                 extended_attributes.set(name, {});
@@ -275,14 +236,14 @@ static OwnPtr<Interface> parse_interface(const StringView& input)
 
 
         consume_whitespace();
         consume_whitespace();
 
 
-        if (consume_if('}'))
+        if (lexer.consume_specific('}'))
             break;
             break;
 
 
-        if (consume_if('[')) {
+        if (lexer.consume_specific('[')) {
             extended_attributes = parse_extended_attributes();
             extended_attributes = parse_extended_attributes();
         }
         }
 
 
-        if (next_is("readonly") || next_is("attribute")) {
+        if (lexer.next_is("readonly") || lexer.next_is("attribute")) {
             parse_attribute(extended_attributes);
             parse_attribute(extended_attributes);
             continue;
             continue;
         }
         }