ソースを参照

LibCpp: Parse braced initialization list

Itamar 4 年 前
コミット
44833f1621

+ 10 - 2
Userland/Libraries/LibCpp/AST.cpp

@@ -536,8 +536,16 @@ void CppCastExpression::dump(size_t indent) const
 void SizeofExpression::dump(size_t indent) const
 {
     ASTNode::dump(indent);
-    if(m_type)
-        m_type->dump(indent+1);
+    if (m_type)
+        m_type->dump(indent + 1);
+}
+
+void BracedInitList::dump(size_t indent) const
+{
+    ASTNode::dump(indent);
+    for (auto& exp : m_expressions) {
+        exp.dump(indent+1);
+    }
 }
 
 }

+ 13 - 0
Userland/Libraries/LibCpp/AST.h

@@ -729,4 +729,17 @@ public:
     RefPtr<Type> m_type;
 };
 
+class BracedInitList : public Expression {
+public:
+    BracedInitList(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
+        : Expression(parent, start, end, filename)
+    {
+    }
+
+    virtual ~BracedInitList() override = default;
+    virtual const char* class_name() const override { return "BracedInitList"; }
+    virtual void dump(size_t indent) const override;
+
+    NonnullRefPtrVector<Expression> m_expressions;
+};
 }

+ 26 - 8
Userland/Libraries/LibCpp/Parser.cpp

@@ -447,9 +447,12 @@ NonnullRefPtr<Expression> Parser::parse_primary_expression(ASTNode& parent)
     if (match_cpp_cast_expression())
         return parse_cpp_cast_expression(parent);
 
-    if(match_sizeof_expression())
+    if (match_sizeof_expression())
         return parse_sizeof_expression(parent);
 
+    if (match_braced_init_list())
+        return parse_braced_init_list(parent);
+
     if (match_name()) {
         if (match_function_call() != TemplatizedMatchResult::NoMatch)
             return parse_function_call(parent);
@@ -851,7 +854,8 @@ bool Parser::match_expression()
         || token_type == Token::Type::Identifier
         || match_unary_expression()
         || match_cpp_cast_expression()
-        || match_sizeof_expression();
+        || match_sizeof_expression()
+        || match_braced_init_list();
 }
 
 bool Parser::eof() const
@@ -1116,13 +1120,9 @@ NonnullRefPtr<MemberDeclaration> Parser::parse_member_declaration(ASTNode& paren
     auto identifier_token = consume(Token::Type::Identifier);
     member_decl->m_name = text_of_token(identifier_token);
 
-    RefPtr<Expression> initial_value;
-    if (match(Token::Type::LeftCurly)) {
-        consume(Token::Type::LeftCurly);
-        initial_value = parse_expression(*member_decl);
-        consume(Token::Type::RightCurly);
+    if (match_braced_init_list()) {
+        member_decl->m_initial_value = parse_braced_init_list(*member_decl);
     }
-    member_decl->m_initial_value = move(initial_value);
 
     consume(Token::Type::Semicolon);
     member_decl->set_end(position());
@@ -1426,4 +1426,22 @@ NonnullRefPtr<SizeofExpression> Parser::parse_sizeof_expression(ASTNode& parent)
     return exp;
 }
 
+bool Parser::match_braced_init_list()
+{
+    return match(Token::Type::LeftCurly);
+}
+
+NonnullRefPtr<BracedInitList> Parser::parse_braced_init_list(ASTNode& parent)
+{
+    auto init_list = create_ast_node<BracedInitList>(parent, position(), {});
+
+    consume(Token::Type::LeftCurly);
+    while (!eof() && peek().type() != Token::Type::RightCurly) {
+        init_list->m_expressions.append(parse_expression(*init_list));
+    }
+    consume(Token::Type::RightCurly);
+    init_list->set_end(position());
+    return init_list;
+}
+
 }

+ 2 - 0
Userland/Libraries/LibCpp/Parser.h

@@ -91,6 +91,7 @@ private:
     bool match_name();
     bool match_cpp_cast_expression();
     bool match_sizeof_expression();
+    bool match_braced_init_list();
 
     enum class TemplatizedMatchResult {
         NoMatch,
@@ -135,6 +136,7 @@ private:
     NonnullRefPtr<Name> parse_name(ASTNode& parent);
     NonnullRefPtr<CppCastExpression> parse_cpp_cast_expression(ASTNode& parent);
     NonnullRefPtr<SizeofExpression> parse_sizeof_expression(ASTNode& parent);
+    NonnullRefPtr<BracedInitList> parse_braced_init_list(ASTNode& parent);
 
     bool match(Token::Type);
     Token consume(Token::Type);