diff options
author | Itamar <itamar8910@gmail.com> | 2021-03-12 17:04:08 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-03-13 10:17:02 +0100 |
commit | 3658c4c567d4076614987a3ab74644df8d487fb0 (patch) | |
tree | 405db3786767576d46114b44f98052e2d72a8862 /Userland/Libraries | |
parent | f21af0922aee3c5fe028f84846beed973b07926f (diff) | |
download | serenity-3658c4c567d4076614987a3ab74644df8d487fb0.zip |
LibCpp: Replace defined preprocessor values when parsing
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibCpp/Parser.cpp | 45 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/Parser.h | 18 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/Preprocessor.cpp | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibCpp/Preprocessor.h | 7 |
4 files changed, 61 insertions, 15 deletions
diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp index 6b923d4958..57b212da23 100644 --- a/Userland/Libraries/LibCpp/Parser.cpp +++ b/Userland/Libraries/LibCpp/Parser.cpp @@ -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)); + } +} } diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h index 12cf2ffd12..789f0618aa 100644 --- a/Userland/Libraries/LibCpp/Parser.h +++ b/Userland/Libraries/LibCpp/Parser.h @@ -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(); }; } diff --git a/Userland/Libraries/LibCpp/Preprocessor.cpp b/Userland/Libraries/LibCpp/Preprocessor.cpp index e276017455..5f4f2c29ae 100644 --- a/Userland/Libraries/LibCpp/Preprocessor.cpp +++ b/Userland/Libraries/LibCpp/Preprocessor.cpp @@ -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; +} + }; diff --git a/Userland/Libraries/LibCpp/Preprocessor.h b/Userland/Libraries/LibCpp/Preprocessor.h index cd402f72bd..e5702b396a 100644 --- a/Userland/Libraries/LibCpp/Preprocessor.h +++ b/Userland/Libraries/LibCpp/Preprocessor.h @@ -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; |