1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 18:17:44 +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));
}
}
}