Serenity Operating System
at master 102 lines 3.2 kB view raw
1/* 2 * Copyright (c) 2021, Itamar S. <itamar8910@gmail.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/DeprecatedFlyString.h> 10#include <AK/DeprecatedString.h> 11#include <AK/Function.h> 12#include <AK/HashMap.h> 13#include <AK/Optional.h> 14#include <AK/StringView.h> 15#include <AK/Vector.h> 16#include <LibCpp/Token.h> 17 18namespace Cpp { 19 20class Preprocessor { 21 22public: 23 explicit Preprocessor(DeprecatedString const& filename, StringView program); 24 Vector<Token> process_and_lex(); 25 Vector<StringView> included_paths() const { return m_included_paths; } 26 27 struct Definition { 28 DeprecatedString key; 29 Vector<DeprecatedString> parameters; 30 DeprecatedString value; 31 DeprecatedFlyString filename; 32 size_t line { 0 }; 33 size_t column { 0 }; 34 }; 35 using Definitions = HashMap<DeprecatedString, Definition>; 36 37 struct Substitution { 38 Vector<Token> original_tokens; 39 Definition defined_value; 40 DeprecatedString processed_value; 41 }; 42 43 Definitions const& definitions() const { return m_definitions; } 44 Vector<Substitution> const& substitutions() const { return m_substitutions; } 45 46 void set_ignore_unsupported_keywords(bool ignore) { m_options.ignore_unsupported_keywords = ignore; } 47 void set_ignore_invalid_statements(bool ignore) { m_options.ignore_invalid_statements = ignore; } 48 void set_keep_include_statements(bool keep) { m_options.keep_include_statements = keep; } 49 50 Function<Definitions(StringView)> definitions_in_header_callback { nullptr }; 51 52 Vector<Token> const& unprocessed_tokens() const { return m_unprocessed_tokens; } 53 54private: 55 void handle_preprocessor_statement(StringView); 56 void handle_include_statement(StringView); 57 void handle_preprocessor_keyword(StringView keyword, GenericLexer& line_lexer); 58 DeprecatedString remove_escaped_newlines(StringView value); 59 60 size_t do_substitution(Vector<Token> const& tokens, size_t token_index, Definition const&); 61 Optional<Definition> create_definition(StringView line); 62 63 struct MacroCall { 64 Token name; 65 struct Argument { 66 Vector<Token> tokens; 67 }; 68 Vector<Argument> arguments; 69 size_t end_token_index { 0 }; 70 }; 71 Optional<MacroCall> parse_macro_call(Vector<Token> const& tokens, size_t token_index); 72 DeprecatedString evaluate_macro_call(MacroCall const&, Definition const&); 73 74 DeprecatedString m_filename; 75 DeprecatedString m_program; 76 77 Vector<Token> m_unprocessed_tokens; 78 Vector<Token> m_processed_tokens; 79 Definitions m_definitions; 80 Vector<Substitution> m_substitutions; 81 82 size_t m_current_line { 0 }; 83 size_t m_current_depth { 0 }; 84 Vector<size_t> m_depths_of_taken_branches; 85 Vector<size_t> m_depths_of_not_taken_branches; 86 87 enum class State { 88 Normal, 89 SkipIfBranch, 90 SkipElseBranch 91 }; 92 State m_state { State::Normal }; 93 94 Vector<StringView> m_included_paths; 95 96 struct Options { 97 bool ignore_unsupported_keywords { false }; 98 bool ignore_invalid_statements { false }; 99 bool keep_include_statements { false }; 100 } m_options; 101}; 102}