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:
parent
5c79297b2c
commit
1d3b5dabc3
4 changed files with 42 additions and 22 deletions
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue