1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 08:47:34 +00:00

LibCpp: Parse ellipsis

We can now parse the printf function declaration :^)
This commit is contained in:
Itamar 2021-03-01 22:33:46 +02:00 committed by Andreas Kling
parent 5c79297b2c
commit 1d3b5dabc3
4 changed files with 42 additions and 22 deletions

View file

@ -83,7 +83,7 @@ void Type::dump(size_t indent) const
ASTNode::dump(indent); ASTNode::dump(indent);
print_indent(indent + 1); print_indent(indent + 1);
String qualifiers_string; String qualifiers_string;
if(!m_qualifiers.is_empty()) if (!m_qualifiers.is_empty())
qualifiers_string = String::formatted("[{}] ", String::join(" ", m_qualifiers)); qualifiers_string = String::formatted("[{}] ", String::join(" ", m_qualifiers));
outln("{}{}", qualifiers_string, m_name); outln("{}{}", qualifiers_string, m_name);
} }
@ -91,11 +91,16 @@ void Type::dump(size_t indent) const
void Parameter::dump(size_t indent) const void Parameter::dump(size_t indent) const
{ {
ASTNode::dump(indent); ASTNode::dump(indent);
if (m_is_ellipsis) {
print_indent(indent + 1);
outln("...");
}
if (!m_name.is_null()) { if (!m_name.is_null()) {
print_indent(indent); print_indent(indent);
outln("{}", m_name); outln("{}", m_name);
} }
m_type->dump(indent + 1); if (m_type)
m_type->dump(indent + 1);
} }
void FunctionDefinition::dump(size_t indent) const void FunctionDefinition::dump(size_t indent) const

View file

@ -202,13 +202,15 @@ public:
virtual const char* class_name() const override { return "Parameter"; } virtual const char* class_name() const override { return "Parameter"; }
virtual void dump(size_t indent) const override; virtual void dump(size_t indent) const override;
Parameter(ASTNode* parent, Optional<Position> start, Optional<Position> end, StringView name, const String& filename) Parameter(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename, StringView name)
: VariableOrParameterDeclaration(parent, start, end, filename) : VariableOrParameterDeclaration(parent, start, end, filename)
{ {
m_name = name; m_name = name;
} }
virtual bool is_parameter() const override { return true; } virtual bool is_parameter() const override { return true; }
bool m_is_ellipsis { false };
}; };
class Type : public ASTNode { class Type : public ASTNode {

View file

@ -24,9 +24,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#undef CPP_DEBUG
#define CPP_DEBUG 1
#ifdef CPP_DEBUG #ifdef CPP_DEBUG
# define DEBUG_SPAM # define DEBUG_SPAM
#endif #endif
@ -560,20 +557,30 @@ Optional<NonnullRefPtrVector<Parameter>> Parser::parse_parameter_list(ASTNode& p
SCOPE_LOGGER(); SCOPE_LOGGER();
NonnullRefPtrVector<Parameter> parameters; NonnullRefPtrVector<Parameter> parameters;
while (peek().m_type != Token::Type::RightParen && !eof()) { while (peek().m_type != Token::Type::RightParen && !eof()) {
auto type = parse_type(parent); if (match_ellipsis()) {
auto last_dot = consume();
while (peek().type() == Token::Type::Dot)
last_dot = consume();
auto param = create_ast_node<Parameter>(parent, position(), last_dot.end(), StringView {});
param->m_is_ellipsis = true;
parameters.append(move(param));
} else {
auto type = parse_type(parent);
auto name_identifier = peek(Token::Type::Identifier); auto name_identifier = peek(Token::Type::Identifier);
if (name_identifier.has_value()) if (name_identifier.has_value())
consume(Token::Type::Identifier); consume(Token::Type::Identifier);
StringView name; StringView name;
if (name_identifier.has_value()) if (name_identifier.has_value())
name = text_of_token(name_identifier.value()); name = text_of_token(name_identifier.value());
auto param = create_ast_node<Parameter>(parent, type->start(), name_identifier.has_value() ? name_identifier.value().m_end : type->end(), name); auto param = create_ast_node<Parameter>(parent, type->start(), name_identifier.has_value() ? name_identifier.value().m_end : type->end(), name);
param->m_type = move(type);
parameters.append(move(param));
}
param->m_type = move(type);
parameters.append(move(param));
if (peek(Token::Type::Comma).has_value()) if (peek(Token::Type::Comma).has_value())
consume(Token::Type::Comma); consume(Token::Type::Comma);
} }
@ -640,12 +647,11 @@ Token Parser::consume()
return m_tokens[m_state.token_index++]; return m_tokens[m_state.token_index++];
} }
Token Parser::peek() const Token Parser::peek(size_t offset) const
{ {
if (eof()) { if (m_state.token_index + offset >= m_tokens.size())
return { Token::Type::EOF_TOKEN, position(), position() }; return { Token::Type::EOF_TOKEN, position(), position() };
} return m_tokens[m_state.token_index + offset];
return m_tokens[m_state.token_index];
} }
Optional<Token> Parser::peek(Token::Type type) const Optional<Token> Parser::peek(Token::Type type) const
@ -1081,10 +1087,16 @@ void Parser::consume_attribute_specification()
if (token.type() == Token::Type::RightParen) { if (token.type() == Token::Type::RightParen) {
--left_count; --left_count;
} }
if(left_count == 0) if (left_count == 0)
return; return;
} }
} }
bool Parser::match_ellipsis()
{
if (m_state.token_index > m_tokens.size() - 3)
return false;
return peek().type() == Token::Type::Dot && peek().type() == Token::Type::Dot && peek().type() == Token::Type::Dot;
}
} }

View file

@ -111,7 +111,7 @@ private:
Token consume(Token::Type); Token consume(Token::Type);
Token consume(); Token consume();
Token consume_keyword(const String&); Token consume_keyword(const String&);
Token peek() const; Token peek(size_t offset = 0) const;
Optional<Token> peek(Token::Type) const; Optional<Token> peek(Token::Type) const;
Position position() const; Position position() const;
StringView text_of_range(Position start, Position end) const; StringView text_of_range(Position start, Position end) const;
@ -163,6 +163,7 @@ private:
Vector<StringView> parse_type_qualifiers(); Vector<StringView> parse_type_qualifiers();
bool match_attribute_specification(); bool match_attribute_specification();
void consume_attribute_specification(); void consume_attribute_specification();
bool match_ellipsis();
}; };
} }