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:
parent
f21af0922a
commit
3658c4c567
8 changed files with 134 additions and 44 deletions
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue