Browse Source

LibCpp: Parse C-Style parse expressions

Itamar 4 years ago
parent
commit
aa717e6a62

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

@@ -547,8 +547,17 @@ void BracedInitList::dump(size_t indent) const
 {
 {
     ASTNode::dump(indent);
     ASTNode::dump(indent);
     for (auto& exp : m_expressions) {
     for (auto& exp : m_expressions) {
-        exp.dump(indent+1);
+        exp.dump(indent + 1);
     }
     }
 }
 }
 
 
+void CStyleCastExpression::dump(size_t indent) const
+{
+    ASTNode::dump(indent);
+    if (m_type)
+        m_type->dump(indent + 1);
+    if (m_expression)
+        m_expression->dump(indent + 1);
+}
+
 }
 }

+ 15 - 2
Userland/Libraries/LibCpp/AST.h

@@ -386,8 +386,6 @@ public:
     }
     }
 };
 };
 
 
-
-
 class BooleanLiteral : public Expression {
 class BooleanLiteral : public Expression {
 public:
 public:
     virtual ~BooleanLiteral() override = default;
     virtual ~BooleanLiteral() override = default;
@@ -716,6 +714,21 @@ public:
     RefPtr<Expression> m_expression;
     RefPtr<Expression> m_expression;
 };
 };
 
 
+class CStyleCastExpression : public Expression {
+public:
+    CStyleCastExpression(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
+        : Expression(parent, start, end, filename)
+    {
+    }
+
+    virtual ~CStyleCastExpression() override = default;
+    virtual const char* class_name() const override { return "CStyleCastExpression"; }
+    virtual void dump(size_t indent) const override;
+
+    RefPtr<Type> m_type;
+    RefPtr<Expression> m_expression;
+};
+
 class SizeofExpression : public Expression {
 class SizeofExpression : public Expression {
 public:
 public:
     SizeofExpression(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
     SizeofExpression(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)

+ 38 - 0
Userland/Libraries/LibCpp/Parser.cpp

@@ -448,6 +448,9 @@ NonnullRefPtr<Expression> Parser::parse_primary_expression(ASTNode& parent)
     if (match_cpp_cast_expression())
     if (match_cpp_cast_expression())
         return parse_cpp_cast_expression(parent);
         return parse_cpp_cast_expression(parent);
 
 
+    if (match_c_style_cast_expression())
+        return parse_c_style_cast_expression(parent);
+
     if (match_sizeof_expression())
     if (match_sizeof_expression())
         return parse_sizeof_expression(parent);
         return parse_sizeof_expression(parent);
 
 
@@ -857,6 +860,7 @@ bool Parser::match_expression()
         || token_type == Token::Type::Identifier
         || token_type == Token::Type::Identifier
         || match_unary_expression()
         || match_unary_expression()
         || match_cpp_cast_expression()
         || match_cpp_cast_expression()
+        || match_c_style_cast_expression()
         || match_sizeof_expression()
         || match_sizeof_expression()
         || match_braced_init_list();
         || match_braced_init_list();
 }
 }
@@ -1394,6 +1398,40 @@ bool Parser::match_cpp_cast_expression()
     return false;
     return false;
 }
 }
 
 
+bool Parser::match_c_style_cast_expression()
+{
+    save_state();
+    ScopeGuard state_guard = [this] { load_state(); };
+
+    if (consume().type() != Token::Type::LeftParen)
+        return false;
+
+    if (match_type() == TemplatizedMatchResult::NoMatch)
+        return false;
+    parse_type(*m_root_node);
+
+    if (consume().type() != Token::Type::RightParen)
+        return false;
+
+    if (!match_expression())
+        return false;
+
+    return true;
+}
+
+NonnullRefPtr<CStyleCastExpression> Parser::parse_c_style_cast_expression(ASTNode& parent)
+{
+    auto parse_exp = create_ast_node<CStyleCastExpression>(parent, position(), {});
+
+    consume(Token::Type::LeftParen);
+    parse_exp->m_type = parse_type(*parse_exp);
+    consume(Token::Type::RightParen);
+    parse_exp->m_expression = parse_expression(*parse_exp);
+    parse_exp->set_end(position());
+
+    return parse_exp;
+}
+
 NonnullRefPtr<CppCastExpression> Parser::parse_cpp_cast_expression(ASTNode& parent)
 NonnullRefPtr<CppCastExpression> Parser::parse_cpp_cast_expression(ASTNode& parent)
 {
 {
     auto cast_expression = create_ast_node<CppCastExpression>(parent, position(), {});
     auto cast_expression = create_ast_node<CppCastExpression>(parent, position(), {});

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

@@ -90,6 +90,7 @@ private:
     bool match_template_arguments();
     bool match_template_arguments();
     bool match_name();
     bool match_name();
     bool match_cpp_cast_expression();
     bool match_cpp_cast_expression();
+    bool match_c_style_cast_expression();
     bool match_sizeof_expression();
     bool match_sizeof_expression();
     bool match_braced_init_list();
     bool match_braced_init_list();
 
 
@@ -137,6 +138,7 @@ private:
     NonnullRefPtr<CppCastExpression> parse_cpp_cast_expression(ASTNode& parent);
     NonnullRefPtr<CppCastExpression> parse_cpp_cast_expression(ASTNode& parent);
     NonnullRefPtr<SizeofExpression> parse_sizeof_expression(ASTNode& parent);
     NonnullRefPtr<SizeofExpression> parse_sizeof_expression(ASTNode& parent);
     NonnullRefPtr<BracedInitList> parse_braced_init_list(ASTNode& parent);
     NonnullRefPtr<BracedInitList> parse_braced_init_list(ASTNode& parent);
+    NonnullRefPtr<CStyleCastExpression> parse_c_style_cast_expression(ASTNode& parent);
 
 
     bool match(Token::Type);
     bool match(Token::Type);
     Token consume(Token::Type);
     Token consume(Token::Type);