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

LibCpp: Replace defined preprocessor values when parsing

This commit is contained in:
Itamar 2021-03-12 17:04:08 +02:00 committed by Andreas Kling
parent f21af0922a
commit 3658c4c567
8 changed files with 134 additions and 44 deletions

View file

@ -37,26 +37,42 @@
namespace Cpp {
Parser::Parser(const StringView& program, const String& filename)
Parser::Parser(const StringView& program, const String& filename, Preprocessor::Definitions&& definitions)
: m_program(program)
, m_definitions(move(definitions))
, m_lines(m_program.split_view("\n", true))
, m_filename(filename)
{
Lexer lexer(m_program);
for (auto& token : lexer.lex()) {
if (token.m_type == Token::Type::Whitespace)
continue;
m_tokens.append(move(token));
}
initialize_program_tokens();
#if CPP_DEBUG
dbgln("Program:");
dbgln("{}", m_program);
dbgln("Tokens:");
for (auto& token : m_tokens) {
dbgln("{} ({}:{}-{}:{})", token.to_string(), token.start().line, token.start().column, token.end().line, token.end().column);
StringView text;
if (token.m_start.line != token.m_end.line || token.m_start.column > token.m_end.column)
text = {};
else
text = text_of_token(token);
dbgln("{} {}:{}-{}:{} ({})", token.to_string(), token.start().line, token.start().column, token.end().line, token.end().column, text);
}
#endif
}
void Parser::initialize_program_tokens()
{
Lexer lexer(m_program);
for (auto& token : lexer.lex()) {
if (token.m_type == Token::Type::Whitespace)
continue;
if (token.m_type == Token::Type::Identifier) {
if (auto defined_value = m_definitions.find(text_of_token(token)); defined_value != m_definitions.end()) {
add_tokens_for_preprocessor(token, defined_value->value);
continue;
}
}
m_tokens.append(move(token));
}
}
NonnullRefPtr<TranslationUnit> Parser::parse()
{
@ -1097,5 +1113,18 @@ bool Parser::match_ellipsis()
return false;
return peek().type() == Token::Type::Dot && peek().type() == Token::Type::Dot && peek().type() == Token::Type::Dot;
}
void Parser::add_tokens_for_preprocessor(Token& replaced_token, Preprocessor::DefinedValue& definition)
{
if (!definition.value.has_value())
return;
Lexer lexer(definition.value.value());
for (auto token : lexer.lex()) {
if (token.type() == Token::Type::Whitespace)
continue;
token.m_start = replaced_token.start();
token.m_end = replaced_token.end();
m_tokens.append(move(token));
}
}
}

View file

@ -27,14 +27,17 @@
#pragma once
#include "AK/NonnullRefPtr.h"
#include <AK/Noncopyable.h>
#include "AST.h"
#include "Preprocessor.h"
#include <LibCpp/Lexer.h>
namespace Cpp {
class Parser final {
AK_MAKE_NONCOPYABLE(Parser);
public:
explicit Parser(const StringView& program, const String& filename);
explicit Parser(const StringView& program, const String& filename, Preprocessor::Definitions&& = {});
~Parser() = default;
NonnullRefPtr<TranslationUnit> parse();
@ -48,6 +51,7 @@ public:
StringView text_of_token(const Cpp::Token& token) const;
void print_tokens() const;
Vector<String> errors() const { return m_errors; }
const Preprocessor::Definitions& definitions() const {return m_definitions;}
private:
enum class DeclarationType {
@ -151,7 +155,15 @@ private:
return node;
}
bool match_attribute_specification();
void consume_attribute_specification();
bool match_ellipsis();
void initialize_program_tokens();
void add_tokens_for_preprocessor(Token& replaced_token, Preprocessor::DefinedValue&);
Vector<StringView> parse_type_qualifiers();
StringView m_program;
Preprocessor::Definitions m_definitions;
Vector<StringView> m_lines;
String m_filename;
Vector<Token> m_tokens;
@ -160,10 +172,6 @@ private:
RefPtr<TranslationUnit> m_root_node;
NonnullRefPtrVector<ASTNode> m_nodes;
Vector<String> m_errors;
Vector<StringView> parse_type_qualifiers();
bool match_attribute_specification();
void consume_attribute_specification();
bool match_ellipsis();
};
}

View file

@ -182,4 +182,10 @@ void Preprocessor::handle_preprocessor_line(const StringView& line)
VERIFY_NOT_REACHED();
}
const String& Preprocessor::processed_text()
{
VERIFY(!m_processed_text.is_null());
return m_processed_text;
}
};

View file

@ -41,14 +41,17 @@ public:
const String& processed_text();
Vector<StringView> included_paths() const { return m_included_paths; }
private:
struct DefinedValue {
Optional<StringView> value;
};
using Definitions = HashMap<StringView, DefinedValue>;
const Definitions& definitions() const { return m_definitions; }
private:
void handle_preprocessor_line(const StringView&);
HashMap<StringView, DefinedValue> m_definitions;
Definitions m_definitions;
const StringView m_program;
StringBuilder m_builder;
Vector<StringView> m_lines;