mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:07:34 +00:00
LibCpp: Introduce DummyASTNode
This allows us to use pase_* methods inside match_* methods, without adding any actual AST nodes to the m_nodes list.
This commit is contained in:
parent
aa717e6a62
commit
e16036b9cc
3 changed files with 38 additions and 16 deletions
|
@ -77,7 +77,8 @@ public:
|
||||||
virtual bool is_function_call() const { return false; }
|
virtual bool is_function_call() const { return false; }
|
||||||
virtual bool is_type() const { return false; }
|
virtual bool is_type() const { return false; }
|
||||||
virtual bool is_declaration() const { return false; }
|
virtual bool is_declaration() const { return false; }
|
||||||
virtual bool is_name() const {return false;}
|
virtual bool is_name() const { return false; }
|
||||||
|
virtual bool is_dummy_node() const { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ASTNode(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
|
ASTNode(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
|
||||||
|
@ -347,7 +348,7 @@ public:
|
||||||
virtual ~Name() override = default;
|
virtual ~Name() override = default;
|
||||||
virtual const char* class_name() const override { return "Name"; }
|
virtual const char* class_name() const override { return "Name"; }
|
||||||
virtual void dump(size_t indent) const override;
|
virtual void dump(size_t indent) const override;
|
||||||
virtual bool is_name() const override {return true;}
|
virtual bool is_name() const override { return true; }
|
||||||
|
|
||||||
Name(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
|
Name(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
|
||||||
: Expression(parent, start, end, filename)
|
: Expression(parent, start, end, filename)
|
||||||
|
@ -756,4 +757,15 @@ public:
|
||||||
|
|
||||||
NonnullRefPtrVector<Expression> m_expressions;
|
NonnullRefPtrVector<Expression> m_expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DummyAstNode : public ASTNode {
|
||||||
|
public:
|
||||||
|
DummyAstNode(ASTNode* parent, Optional<Position> start, Optional<Position> end, const String& filename)
|
||||||
|
: ASTNode(parent, start, end, filename)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual bool is_dummy_node() const override { return true; }
|
||||||
|
virtual const char* class_name() const override { return "DummyAstNode"; }
|
||||||
|
virtual void dump(size_t) const override { }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,7 @@ Parser::TemplatizedMatchResult Parser::match_type()
|
||||||
|
|
||||||
if (!match_name())
|
if (!match_name())
|
||||||
return TemplatizedMatchResult::NoMatch;
|
return TemplatizedMatchResult::NoMatch;
|
||||||
parse_name(*m_root_node);
|
parse_name(get_dummy_node());
|
||||||
|
|
||||||
if (peek(Token::Type::Less).has_value()) {
|
if (peek(Token::Type::Less).has_value()) {
|
||||||
if (match_template_arguments()) {
|
if (match_template_arguments()) {
|
||||||
|
@ -287,7 +287,7 @@ bool Parser::match_template_arguments()
|
||||||
while (!eof() && peek().type() != Token::Type::Greater) {
|
while (!eof() && peek().type() != Token::Type::Greater) {
|
||||||
if (match_type() == TemplatizedMatchResult::NoMatch)
|
if (match_type() == TemplatizedMatchResult::NoMatch)
|
||||||
return false;
|
return false;
|
||||||
parse_type(*m_root_node);
|
parse_type(get_dummy_node());
|
||||||
}
|
}
|
||||||
|
|
||||||
return peek().type() == Token::Type::Greater;
|
return peek().type() == Token::Type::Greater;
|
||||||
|
@ -320,7 +320,7 @@ bool Parser::match_variable_declaration()
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY(m_root_node);
|
VERIFY(m_root_node);
|
||||||
parse_type(*m_root_node);
|
parse_type(get_dummy_node());
|
||||||
|
|
||||||
// Identifier
|
// Identifier
|
||||||
if (!peek(Token::Type::Identifier).has_value()) {
|
if (!peek(Token::Type::Identifier).has_value()) {
|
||||||
|
@ -668,7 +668,7 @@ bool Parser::match_function_declaration()
|
||||||
if (match_type() == TemplatizedMatchResult::NoMatch)
|
if (match_type() == TemplatizedMatchResult::NoMatch)
|
||||||
return false;
|
return false;
|
||||||
VERIFY(m_root_node);
|
VERIFY(m_root_node);
|
||||||
parse_type(*m_root_node);
|
parse_type(get_dummy_node());
|
||||||
|
|
||||||
if (!peek(Token::Type::Identifier).has_value())
|
if (!peek(Token::Type::Identifier).has_value())
|
||||||
return false;
|
return false;
|
||||||
|
@ -888,7 +888,7 @@ RefPtr<ASTNode> Parser::node_at(Position pos) const
|
||||||
auto index = index_of_node_at(pos);
|
auto index = index_of_node_at(pos);
|
||||||
if (!index.has_value())
|
if (!index.has_value())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return m_nodes[index.value()];
|
return m_state.nodes[index.value()];
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<size_t> Parser::index_of_node_at(Position pos) const
|
Optional<size_t> Parser::index_of_node_at(Position pos) const
|
||||||
|
@ -902,12 +902,12 @@ Optional<size_t> Parser::index_of_node_at(Position pos) const
|
||||||
return Position { node.end().line - node.start().line, node.start().line != node.end().line ? 0 : node.end().column - node.start().column };
|
return Position { node.end().line - node.start().line, node.start().line != node.end().line ? 0 : node.end().column - node.start().column };
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t node_index = 0; node_index < m_nodes.size(); ++node_index) {
|
for (size_t node_index = 0; node_index < m_state.nodes.size(); ++node_index) {
|
||||||
auto& node = m_nodes[node_index];
|
auto& node = m_state.nodes[node_index];
|
||||||
if (node.start() > pos || node.end() < pos)
|
if (node.start() > pos || node.end() < pos)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!match_node_index.has_value() || (node_span(node) < node_span(m_nodes[match_node_index.value()])))
|
if (!match_node_index.has_value() || (node_span(node) < node_span(m_state.nodes[match_node_index.value()])))
|
||||||
match_node_index = node_index;
|
match_node_index = node_index;
|
||||||
}
|
}
|
||||||
return match_node_index;
|
return match_node_index;
|
||||||
|
@ -945,12 +945,12 @@ Parser::TemplatizedMatchResult Parser::match_function_call()
|
||||||
ScopeGuard state_guard = [this] { load_state(); };
|
ScopeGuard state_guard = [this] { load_state(); };
|
||||||
if (!match_name())
|
if (!match_name())
|
||||||
return TemplatizedMatchResult::NoMatch;
|
return TemplatizedMatchResult::NoMatch;
|
||||||
parse_name(*m_root_node);
|
parse_name(get_dummy_node());
|
||||||
|
|
||||||
bool is_templatized = false;
|
bool is_templatized = false;
|
||||||
if (match_template_arguments()) {
|
if (match_template_arguments()) {
|
||||||
is_templatized = true;
|
is_templatized = true;
|
||||||
parse_template_arguments(*m_root_node);
|
parse_template_arguments(get_dummy_node());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!match(Token::Type::LeftParen))
|
if (!match(Token::Type::LeftParen))
|
||||||
|
@ -1408,7 +1408,7 @@ bool Parser::match_c_style_cast_expression()
|
||||||
|
|
||||||
if (match_type() == TemplatizedMatchResult::NoMatch)
|
if (match_type() == TemplatizedMatchResult::NoMatch)
|
||||||
return false;
|
return false;
|
||||||
parse_type(*m_root_node);
|
parse_type(get_dummy_node());
|
||||||
|
|
||||||
if (consume().type() != Token::Type::RightParen)
|
if (consume().type() != Token::Type::RightParen)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -155,6 +155,7 @@ private:
|
||||||
struct State {
|
struct State {
|
||||||
size_t token_index { 0 };
|
size_t token_index { 0 };
|
||||||
Vector<String> errors;
|
Vector<String> errors;
|
||||||
|
NonnullRefPtrVector<ASTNode> nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
void error(StringView message = {});
|
void error(StringView message = {});
|
||||||
|
@ -164,7 +165,9 @@ private:
|
||||||
create_ast_node(ASTNode& parent, const Position& start, Optional<Position> end, Args&&... args)
|
create_ast_node(ASTNode& parent, const Position& start, Optional<Position> end, Args&&... args)
|
||||||
{
|
{
|
||||||
auto node = adopt(*new T(&parent, start, end, m_filename, forward<Args>(args)...));
|
auto node = adopt(*new T(&parent, start, end, m_filename, forward<Args>(args)...));
|
||||||
m_nodes.append(node);
|
if(!parent.is_dummy_node()) {
|
||||||
|
m_state.nodes.append(node);
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,11 +175,19 @@ private:
|
||||||
create_root_ast_node(const Position& start, Position end)
|
create_root_ast_node(const Position& start, Position end)
|
||||||
{
|
{
|
||||||
auto node = adopt(*new TranslationUnit(nullptr, start, end, m_filename));
|
auto node = adopt(*new TranslationUnit(nullptr, start, end, m_filename));
|
||||||
m_nodes.append(node);
|
m_state.nodes.append(node);
|
||||||
m_root_node = node;
|
m_root_node = node;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DummyAstNode& get_dummy_node()
|
||||||
|
{
|
||||||
|
static NonnullRefPtr<DummyAstNode> dummy = adopt(*new DummyAstNode(nullptr, {}, {}, {}));
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool match_attribute_specification();
|
bool match_attribute_specification();
|
||||||
void consume_attribute_specification();
|
void consume_attribute_specification();
|
||||||
bool match_ellipsis();
|
bool match_ellipsis();
|
||||||
|
@ -191,7 +202,6 @@ private:
|
||||||
State m_state;
|
State m_state;
|
||||||
Vector<State> m_saved_states;
|
Vector<State> m_saved_states;
|
||||||
RefPtr<TranslationUnit> m_root_node;
|
RefPtr<TranslationUnit> m_root_node;
|
||||||
NonnullRefPtrVector<ASTNode> m_nodes;
|
|
||||||
|
|
||||||
Vector<TokenAndPreprocessorDefinition> m_replaced_preprocessor_tokens;
|
Vector<TokenAndPreprocessorDefinition> m_replaced_preprocessor_tokens;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue