diff --git a/src/Parser/Parsing/ILexer.h b/src/Parser/Parsing/ILexer.h index e0a53c3c..9542574e 100644 --- a/src/Parser/Parsing/ILexer.h +++ b/src/Parser/Parsing/ILexer.h @@ -3,11 +3,10 @@ #include "IParserLineStream.h" #include "Parsing/IParserValue.h" -template class ILexer -{ - // TokenType must inherit IParserValue - static_assert(std::is_base_of::value); +#include +template TokenType> class ILexer +{ public: ILexer() = default; virtual ~ILexer() = default; @@ -16,10 +15,10 @@ public: ILexer& operator=(const ILexer& other) = default; ILexer& operator=(ILexer&& other) noexcept = default; - virtual const TokenType& GetToken(unsigned index) = 0; - virtual void PopTokens(int amount) = 0; + virtual const TokenType& GetToken(size_t index) = 0; + virtual void PopTokens(size_t amount) = 0; - _NODISCARD virtual bool IsEof() = 0; - _NODISCARD virtual const TokenPos& GetPos() = 0; - _NODISCARD virtual ParserLine GetLineForPos(const TokenPos& pos) const = 0; + [[nodiscard]] virtual bool IsEof() = 0; + [[nodiscard]] virtual const TokenPos& GetPos() = 0; + [[nodiscard]] virtual ParserLine GetLineForPos(const TokenPos& pos) const = 0; }; diff --git a/src/Parser/Parsing/Impl/AbstractLexer.h b/src/Parser/Parsing/Impl/AbstractLexer.h index 637be807..34b6f2dd 100644 --- a/src/Parser/Parsing/Impl/AbstractLexer.h +++ b/src/Parser/Parsing/Impl/AbstractLexer.h @@ -7,21 +7,82 @@ #include "Utils/StringUtils.h" #include +#include #include #include -template class AbstractLexer : public ILexer +template TokenType> class AbstractLexer : public ILexer { - // TokenType must inherit IParserValue - static_assert(std::is_base_of::value); +public: + const TokenType& GetToken(const size_t index) override + { + while (index >= m_token_cache.size()) + m_token_cache.emplace_back(GetNextToken()); + + return m_token_cache[index]; + } + + void PopTokens(size_t amount) override + { + if (amount == 0 || m_token_cache.empty()) + return; + + if (m_token_cache.size() <= amount) + { + const auto& lastToken = m_token_cache.back(); + while ( + !m_line_cache.empty() + && (m_line_cache.front().m_line_number != lastToken.GetPos().m_line || *m_line_cache.front().m_filename != lastToken.GetPos().m_filename.get())) + { + m_line_cache.pop_front(); + m_line_index--; + } + m_token_cache.clear(); + } + else + { + m_token_cache.erase(m_token_cache.begin(), m_token_cache.begin() + amount); + const auto& firstToken = m_token_cache.front(); + while (!m_line_cache.empty() + && (m_line_cache.front().m_line_number != firstToken.GetPos().m_line + || *m_line_cache.front().m_filename != firstToken.GetPos().m_filename.get())) + { + m_line_cache.pop_front(); + m_line_index--; + } + } + } + + [[nodiscard]] bool IsEof() override + { + return GetToken(0).IsEof(); + } + + [[nodiscard]] const TokenPos& GetPos() override + { + return GetToken(0).GetPos(); + } + + [[nodiscard]] ParserLine GetLineForPos(const TokenPos& pos) const override + { + for (const auto& line : m_line_cache) + { + if (line.m_filename && *line.m_filename == pos.m_filename.get() && line.m_line_number == pos.m_line) + { + return line; + } + } + + return ParserLine(); + } protected: std::deque m_token_cache; std::deque m_line_cache; - IParserLineStream* const m_stream; + IParserLineStream* m_stream; - unsigned m_line_index; - unsigned m_current_line_offset; + size_t m_line_index; + size_t m_current_line_offset; explicit AbstractLexer(IParserLineStream* stream) : m_stream(stream), @@ -83,28 +144,28 @@ protected: return m_line_cache[peekLine].m_line[peekLineOffset]; } - _NODISCARD const ParserLine& CurrentLine() const + [[nodiscard]] const ParserLine& CurrentLine() const { return m_line_cache[m_line_index]; } - _NODISCARD bool IsLineEnd() const + [[nodiscard]] bool IsLineEnd() const { return m_current_line_offset >= CurrentLine().m_line.size(); } - _NODISCARD bool NextCharInLineIs(const char c) + [[nodiscard]] bool NextCharInLineIs(const char c) { return !IsLineEnd() && PeekChar() == c; } - _NODISCARD TokenPos GetPreviousCharacterPos() const + [[nodiscard]] TokenPos GetPreviousCharacterPos() const { const auto& currentLine = CurrentLine(); return TokenPos(*currentLine.m_filename, currentLine.m_line_number, m_current_line_offset); } - _NODISCARD TokenPos GetNextCharacterPos() + [[nodiscard]] TokenPos GetNextCharacterPos() { const auto& currentLine = CurrentLine(); if (m_current_line_offset + 1 >= currentLine.m_line.size()) @@ -227,7 +288,7 @@ protected: m_current_line_offset += numberLength - 1; } - _NODISCARD bool IsIntegerNumber() const + [[nodiscard]] bool IsIntegerNumber() const { const auto& currentLine = CurrentLine(); const auto* currentCharacter = ¤tLine.m_line.c_str()[m_current_line_offset - 1]; @@ -350,67 +411,4 @@ protected: integerValue = ReadInteger(); } } - -public: - const TokenType& GetToken(unsigned index) override - { - while (index >= m_token_cache.size()) - m_token_cache.emplace_back(GetNextToken()); - - return m_token_cache[index]; - } - - void PopTokens(int amount) override - { - if (amount <= 0 || m_token_cache.empty()) - return; - - if (static_cast(m_token_cache.size()) <= amount) - { - const auto& lastToken = m_token_cache.back(); - while ( - !m_line_cache.empty() - && (m_line_cache.front().m_line_number != lastToken.GetPos().m_line || *m_line_cache.front().m_filename != lastToken.GetPos().m_filename.get())) - { - m_line_cache.pop_front(); - m_line_index--; - } - m_token_cache.clear(); - } - else - { - m_token_cache.erase(m_token_cache.begin(), m_token_cache.begin() + amount); - const auto& firstToken = m_token_cache.front(); - while (!m_line_cache.empty() - && (m_line_cache.front().m_line_number != firstToken.GetPos().m_line - || *m_line_cache.front().m_filename != firstToken.GetPos().m_filename.get())) - { - m_line_cache.pop_front(); - m_line_index--; - } - } - } - - _NODISCARD bool IsEof() override - { - return GetToken(0).IsEof(); - } - - _NODISCARD const TokenPos& GetPos() override - { - return GetToken(0).GetPos(); - } - - _NODISCARD ParserLine GetLineForPos(const TokenPos& pos) const override - { - for (const auto& line : m_line_cache) - { - if (line.m_filename && *line.m_filename == pos.m_filename.get() && line.m_line_number == pos.m_line) - { - return line; - } - } - - return ParserLine(); - } }; diff --git a/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp b/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp index 38e80040..9c241627 100644 --- a/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp +++ b/src/Parser/Parsing/Impl/DefinesStreamProxy.cpp @@ -5,7 +5,6 @@ #include "Parsing/Simple/Expression/ISimpleExpression.h" #include "Parsing/Simple/Expression/SimpleExpressionMatchers.h" #include "Parsing/Simple/SimpleExpressionInterpreter.h" -#include "Utils/ClassUtils.h" #include "Utils/StringUtils.h" #include @@ -114,7 +113,7 @@ void DefinesStreamProxy::Define::IdentifyParameters(const std::vector= inputSize) - throw new ParsingException(TokenPos(*line.m_filename, line.m_line_number, static_cast(linePos + 1)), - "Token-pasting operator cannot be used on unclosed string"); + throw ParsingException(TokenPos(*line.m_filename, line.m_line_number, static_cast(linePos + 1)), + "Token-pasting operator cannot be used on unclosed string"); offset++; } @@ -743,12 +736,16 @@ namespace unsigned m_end; }; - void EmitPastedTokens( - ParserLine& line, unsigned& linePos, std::ostream& out, const std::string& input, const TokenPasteToken& token0, const TokenPasteToken& token1) + void EmitPastedTokens(const ParserLine& line, + const unsigned& linePos, + std::ostream& out, + const std::string& input, + const TokenPasteToken& token0, + const TokenPasteToken& token1) { if ((token0.m_type == TokenPasteTokenType::STRING) != (token1.m_type == TokenPasteTokenType::STRING)) - throw new ParsingException(TokenPos(*line.m_filename, line.m_line_number, static_cast(linePos + 1)), - "String token can only use token-pasting operator on other string token"); + throw ParsingException(TokenPos(*line.m_filename, line.m_line_number, static_cast(linePos + 1)), + "String token can only use token-pasting operator on other string token"); if (token0.m_type == TokenPasteTokenType::STRING) { out << '"'; @@ -767,7 +764,7 @@ namespace } // namespace void DefinesStreamProxy::ProcessTokenPastingOperators( - ParserLine& line, unsigned& linePos, std::vector& callstack, std::string& input, unsigned& inputPos) + const ParserLine& line, const unsigned& linePos, std::vector& callstack, std::string& input, unsigned& inputPos) { std::ostringstream ss; @@ -789,7 +786,7 @@ void DefinesStreamProxy::ProcessTokenPastingOperators( if (c == '#' && IsTokenPastingOperatorForwardLookup(input, i)) { if (currentToken.m_type == TokenPasteTokenType::NONE) - throw new ParsingException(CreatePos(line, linePos), "Cannot use token-pasting operator without previous token"); + throw ParsingException(CreatePos(line, linePos), "Cannot use token-pasting operator without previous token"); if (previousToken.m_end < currentToken.m_start) ss << std::string(input, previousToken.m_end, currentToken.m_start - previousToken.m_end); @@ -816,12 +813,12 @@ void DefinesStreamProxy::ProcessTokenPastingOperators( ss << std::string(input, previousToken.m_end, inputSize - previousToken.m_end); if (pasteNext) - throw new ParsingException(CreatePos(line, linePos), "Cannot use token-pasting operator without following token"); + throw ParsingException(CreatePos(line, linePos), "Cannot use token-pasting operator without following token"); input = ss.str(); } -void DefinesStreamProxy::InsertMacroParameters(std::ostringstream& out, const DefinesStreamProxy::Define* macro, std::vector& parameterValues) +void DefinesStreamProxy::InsertMacroParameters(std::ostringstream& out, const Define* macro, const std::vector& parameterValues) { if (parameterValues.empty() || macro->m_parameter_positions.empty()) { @@ -829,7 +826,7 @@ void DefinesStreamProxy::InsertMacroParameters(std::ostringstream& out, const De return; } - auto lastPos = 0u; + auto lastPos = 0uz; for (const auto& parameterPosition : macro->m_parameter_positions) { if (lastPos < parameterPosition.m_parameter_position) @@ -857,7 +854,7 @@ void DefinesStreamProxy::ExpandMacro(ParserLine& line, std::ostringstream& out, std::vector& callstack, const DefinesStreamProxy::Define* macro, - std::vector& parameterValues) + const std::vector& parameterValues) { std::ostringstream rawOutput; InsertMacroParameters(rawOutput, macro, parameterValues); @@ -873,7 +870,7 @@ void DefinesStreamProxy::ExpandMacro(ParserLine& line, } void DefinesStreamProxy::ContinueMacroParameters( - const ParserLine& line, unsigned& linePos, MacroParameterState& state, const std::string& input, unsigned& inputPos) + const ParserLine& line, const unsigned& linePos, MacroParameterState& state, const std::string& input, unsigned& inputPos) { const auto inputLength = input.size(); while (state.m_parameter_state != ParameterState::NOT_IN_PARAMETERS && inputPos < inputLength) diff --git a/src/Parser/Parsing/Impl/DefinesStreamProxy.h b/src/Parser/Parsing/Impl/DefinesStreamProxy.h index 28d8564a..d9beffb6 100644 --- a/src/Parser/Parsing/Impl/DefinesStreamProxy.h +++ b/src/Parser/Parsing/Impl/DefinesStreamProxy.h @@ -107,26 +107,29 @@ private: _NODISCARD bool MatchIfdefDirective(const ParserLine& line, size_t directiveStartPosition, size_t directiveEndPosition); _NODISCARD bool MatchElseDirective(const ParserLine& line, size_t directiveStartPosition, size_t directiveEndPosition); _NODISCARD bool MatchEndifDirective(const ParserLine& line, size_t directiveStartPosition, size_t directiveEndPosition); - _NODISCARD bool MatchDirectives(ParserLine& line); + _NODISCARD bool MatchDirectives(const ParserLine& line); - void ExtractParametersFromMacroUsage(const ParserLine& line, unsigned& linePos, MacroParameterState& state, const std::string& input, unsigned& inputPos); - bool FindMacroForIdentifier(const std::string& input, unsigned wordStart, unsigned wordEnd, const Define*& value) const; + static void ExtractParametersFromMacroUsage( + const ParserLine& line, const unsigned& linePos, MacroParameterState& state, const std::string& input, unsigned& inputPos); + bool FindMacroForIdentifier(const std::string& input, unsigned identifierStart, unsigned identifierEnd, const Define*& value) const; static bool MatchDefinedExpression(const ParserLine& line, size_t& pos, std::string& definitionName); void ExpandDefinedExpressions(ParserLine& line) const; - bool FindNextMacro(const std::string& input, unsigned& inputPos, unsigned& defineStart, const DefinesStreamProxy::Define*& define); + bool FindNextMacro(const std::string& input, unsigned& inputPos, unsigned& defineStart, const DefinesStreamProxy::Define*& define) const; - void ProcessTokenPastingOperators(ParserLine& line, unsigned& linePos, std::vector& callstack, std::string& input, unsigned& inputPos); - void InsertMacroParameters(std::ostringstream& out, const DefinesStreamProxy::Define* macro, std::vector& parameterValues); + static void ProcessTokenPastingOperators( + const ParserLine& line, const unsigned& linePos, std::vector& callstack, std::string& input, unsigned& inputPos); + static void InsertMacroParameters(std::ostringstream& out, const DefinesStreamProxy::Define* macro, const std::vector& parameterValues); void ExpandMacro(ParserLine& line, unsigned& linePos, std::ostringstream& out, std::vector& callstack, const DefinesStreamProxy::Define* macro, - std::vector& parameterValues); + const std::vector& parameterValues); - void ContinueMacroParameters(const ParserLine& line, unsigned& linePos, MacroParameterState& state, const std::string& input, unsigned& inputPos); + static void + ContinueMacroParameters(const ParserLine& line, const unsigned& linePos, MacroParameterState& state, const std::string& input, unsigned& inputPos); void ContinueMultiLineMacro(ParserLine& line); void ProcessNestedMacros(ParserLine& line, unsigned& linePos, std::vector& callstack, std::string& input, unsigned& inputPos); diff --git a/src/Parser/Parsing/Matcher/MatcherResult.cpp b/src/Parser/Parsing/Matcher/MatcherResult.cpp new file mode 100644 index 00000000..b79de9ce --- /dev/null +++ b/src/Parser/Parsing/Matcher/MatcherResult.cpp @@ -0,0 +1,47 @@ +#include "MatcherResult.h" + +namespace +{ + // The highest bit is the fabricated flag + constexpr size_t FABRICATED_FLAG_MASK = 1uz << (sizeof(size_t) * 8uz - 1uz); + constexpr size_t TOKEN_INDEX_MASK = ~FABRICATED_FLAG_MASK; +} // namespace + +MatcherResultTokenIndex::MatcherResultTokenIndex(const size_t index, const bool isFabricated) +{ + m_token_index = index & TOKEN_INDEX_MASK; + if (isFabricated) + m_token_index |= FABRICATED_FLAG_MASK; +} + +bool MatcherResultTokenIndex::IsFabricated() const +{ + return m_token_index & FABRICATED_FLAG_MASK; +} + +size_t MatcherResultTokenIndex::GetTokenIndex() const +{ + return m_token_index & TOKEN_INDEX_MASK; +} + +MatcherResultCapture::MatcherResultCapture(const int captureId, const unsigned tokenIndex) + : MatcherResultCapture(captureId, tokenIndex, false) +{ +} + +MatcherResultCapture::MatcherResultCapture(const int captureId, const unsigned tokenIndex, const bool isFabricated) + : m_capture_id(captureId), + m_token_index(tokenIndex, isFabricated) +{ +} + +MatcherResultCapture::MatcherResultCapture(const int captureId, const MatcherResultTokenIndex index) + : m_capture_id(captureId), + m_token_index(index) +{ +} + +int MatcherResultCapture::GetCaptureId() const +{ + return m_capture_id; +} diff --git a/src/Parser/Parsing/Matcher/MatcherResult.h b/src/Parser/Parsing/Matcher/MatcherResult.h index f3e99e9d..719f30d5 100644 --- a/src/Parser/Parsing/Matcher/MatcherResult.h +++ b/src/Parser/Parsing/Matcher/MatcherResult.h @@ -1,89 +1,40 @@ #pragma once #include "Parsing/IParserValue.h" -#include "Utils/ClassUtils.h" +#include +#include #include -#include #include -template class MatcherResult +class MatcherResultTokenIndex { - // TokenType must inherit IParserValue - static_assert(std::is_base_of::value); - public: - class TokenIndex - { - static constexpr unsigned FABRICATED_FLAG_MASK = std::numeric_limits::max() ^ std::numeric_limits::max(); - static constexpr unsigned TOKEN_INDEX_MASK = ~FABRICATED_FLAG_MASK; - - unsigned m_token_index; - - public: - TokenIndex(const unsigned index, const bool isFabricated) - { - m_token_index = index & TOKEN_INDEX_MASK; - if (isFabricated) - m_token_index |= FABRICATED_FLAG_MASK; - } - - _NODISCARD bool IsFabricated() const - { - return m_token_index & FABRICATED_FLAG_MASK; - } - - _NODISCARD unsigned GetTokenIndex() const - { - return m_token_index & TOKEN_INDEX_MASK; - } - }; - - class Capture - { - public: - int m_capture_id; - TokenIndex m_token_index; - - Capture(const int captureId, const unsigned tokenIndex) - : Capture(captureId, tokenIndex, false) - { - } - - Capture(const int captureId, const unsigned tokenIndex, const bool isFabricated) - : m_capture_id(captureId), - m_token_index(tokenIndex, isFabricated) - { - } - - Capture(const int captureId, const TokenIndex index) - : m_capture_id(captureId), - m_token_index(index) - { - } - - _NODISCARD int GetCaptureId() const - { - return m_capture_id; - } - }; - - bool m_matches; - unsigned m_consumed_token_count; - std::vector m_tags; - std::vector m_captures; - std::vector m_matched_tokens; - std::vector m_fabricated_tokens; + MatcherResultTokenIndex(size_t index, bool isFabricated); + [[nodiscard]] bool IsFabricated() const; + [[nodiscard]] size_t GetTokenIndex() const; private: - MatcherResult(const bool matches, const unsigned consumedTokenCount) - : m_matches(matches), - m_consumed_token_count(consumedTokenCount) - { - } + size_t m_token_index; +}; +class MatcherResultCapture +{ public: - static MatcherResult Match(unsigned consumedTokenCount) + MatcherResultCapture(int captureId, unsigned tokenIndex); + MatcherResultCapture(int captureId, unsigned tokenIndex, bool isFabricated); + MatcherResultCapture(int captureId, MatcherResultTokenIndex index); + + [[nodiscard]] int GetCaptureId() const; + + int m_capture_id; + MatcherResultTokenIndex m_token_index; +}; + +template TokenType> class MatcherResult +{ +public: + static MatcherResult Match(const unsigned consumedTokenCount) { return MatcherResult(true, consumedTokenCount); } @@ -98,12 +49,13 @@ public: m_consumed_token_count += other.m_consumed_token_count; if (!other.m_tags.empty()) - std::copy(other.m_tags.begin(), other.m_tags.end(), std::back_inserter(m_tags)); + std::ranges::copy(other.m_tags, std::back_inserter(m_tags)); for (const auto& capture : other.m_captures) { if (capture.m_token_index.IsFabricated()) - m_captures.emplace_back(capture.GetCaptureId(), TokenIndex(m_fabricated_tokens.size() + capture.m_token_index.GetTokenIndex(), true)); + m_captures.emplace_back(capture.GetCaptureId(), + MatcherResultTokenIndex(m_fabricated_tokens.size() + capture.m_token_index.GetTokenIndex(), true)); else m_captures.emplace_back(capture.GetCaptureId(), capture.m_token_index); } @@ -121,4 +73,18 @@ public: m_fabricated_tokens.emplace_back(std::move(fabricated)); } } + + bool m_matches; + unsigned m_consumed_token_count; + std::vector m_tags; + std::vector m_captures; + std::vector m_matched_tokens; + std::vector m_fabricated_tokens; + +private: + MatcherResult(const bool matches, const unsigned consumedTokenCount) + : m_matches(matches), + m_consumed_token_count(consumedTokenCount) + { + } }; diff --git a/src/Parser/Parsing/Sequence/SequenceResult.h b/src/Parser/Parsing/Sequence/SequenceResult.h index 764e43ea..fb268bd7 100644 --- a/src/Parser/Parsing/Sequence/SequenceResult.h +++ b/src/Parser/Parsing/Sequence/SequenceResult.h @@ -5,9 +5,10 @@ #include "Parsing/ParsingException.h" #include "Utils/ClassUtils.h" +#include #include -template class SequenceResult +template TokenType> class SequenceResult { class Capture { @@ -21,9 +22,6 @@ template class SequenceResult } }; - // TokenType must inherit IParserValue - static_assert(std::is_base_of::value); - std::vector m_tags; std::unordered_map m_captures; @@ -34,7 +32,7 @@ public: : m_tags(result.m_tags), m_tag_offset(0) { - for (const typename MatcherResult::Capture& capture : result.m_captures) + for (const MatcherResultCapture& capture : result.m_captures) { if (capture.m_token_index.IsFabricated()) m_captures[capture.GetCaptureId()].m_tokens.push_back(result.m_fabricated_tokens[capture.m_token_index.GetTokenIndex()]); diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.cpp b/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.cpp index a5f21c30..8a347444 100644 --- a/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.cpp +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.cpp @@ -7,6 +7,7 @@ #include #include +#include static constexpr int TAG_EXPRESSION = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 1; static constexpr int TAG_OPERAND = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 2; @@ -103,7 +104,7 @@ std::unique_ptr SimpleExpressionMatchers::ProcessConditionalO return std::make_unique(std::move(condition), std::move(trueExpression), std::move(falseExpression)); } -std::unique_ptr SimpleExpressionMatchers::ProcessOperand(SequenceResult& result) const +std::unique_ptr SimpleExpressionMatchers::ProcessOperand(SequenceResult& result) { const auto& operandToken = result.NextCapture(CAPTURE_OPERAND); @@ -133,7 +134,7 @@ std::unique_ptr SimpleExpressionMatchers::ProcessExpression(S return nullptr; std::vector> operands; - std::list> operators; + std::list> operators; while (true) { @@ -200,7 +201,7 @@ std::unique_ptr SimpleExpressionMatchers::ProcessExpression(S } operators.sort( - [](const std::pair& p1, const std::pair& p2) + [](const std::pair& p1, const std::pair& p2) { if (p1.second->m_precedence != p2.second->m_precedence) return p1.second->m_precedence > p2.second->m_precedence; @@ -219,7 +220,7 @@ std::unique_ptr SimpleExpressionMatchers::ProcessExpression(S operators.pop_back(); - for (auto& [opIndex, _] : operators) + for (auto& opIndex : operators | std::views::keys) { if (opIndex > operatorIndex) opIndex--; diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.h b/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.h index 021688e2..aaf02bc9 100644 --- a/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.h +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionMatchers.h @@ -59,7 +59,7 @@ private: std::unique_ptr ProcessExpressionInParenthesis(SequenceResult& result) const; std::unique_ptr ProcessConditionalOperation(std::unique_ptr condition, SequenceResult& result) const; - std::unique_ptr ProcessOperand(SequenceResult& result) const; + static std::unique_ptr ProcessOperand(SequenceResult& result); public: std::unique_ptr Expression(const supplier_t* labelSupplier) const; diff --git a/src/Parser/Parsing/Simple/SimpleLexer.cpp b/src/Parser/Parsing/Simple/SimpleLexer.cpp index 63d5a556..d20fee7f 100644 --- a/src/Parser/Parsing/Simple/SimpleLexer.cpp +++ b/src/Parser/Parsing/Simple/SimpleLexer.cpp @@ -14,7 +14,12 @@ SimpleLexer::MultiCharacterTokenLookupEntry::MultiCharacterTokenLookupEntry(cons SimpleLexer::SimpleLexer(IParserLineStream* stream) : AbstractLexer(stream), - m_config{false, true, false, true, true, {}}, + m_config{.m_emit_new_line_tokens = false, + .m_read_strings = true, + .m_string_escape_sequences = false, + .m_read_integer_numbers = true, + .m_read_floating_point_numbers = true, + .m_multi_character_tokens = {}}, m_check_for_multi_character_tokens(false), m_last_line(1) { diff --git a/src/Parser/Parsing/Simple/SimpleLexer.h b/src/Parser/Parsing/Simple/SimpleLexer.h index c1220d52..bd6e45dc 100644 --- a/src/Parser/Parsing/Simple/SimpleLexer.h +++ b/src/Parser/Parsing/Simple/SimpleLexer.h @@ -7,7 +7,7 @@ #include #include -class SimpleLexer : public AbstractLexer +class SimpleLexer final : public AbstractLexer { public: class Config @@ -30,6 +30,9 @@ public: std::vector m_multi_character_tokens; }; + explicit SimpleLexer(IParserLineStream* stream); + SimpleLexer(IParserLineStream* stream, Config config); + protected: class MultiCharacterTokenLookupEntry { @@ -41,10 +44,6 @@ protected: MultiCharacterTokenLookupEntry(int id, std::string value); }; - Config m_config; - bool m_check_for_multi_character_tokens; - int m_last_line; - std::unique_ptr m_multi_character_token_lookup[std::numeric_limits::max() + 1]; void AddMultiCharacterTokenConfigToLookup(Config::MultiCharacterToken tokenConfig); @@ -52,7 +51,7 @@ protected: SimpleParserValue GetNextToken() override; -public: - explicit SimpleLexer(IParserLineStream* stream); - SimpleLexer(IParserLineStream* stream, Config config); + Config m_config; + bool m_check_for_multi_character_tokens; + size_t m_last_line; }; diff --git a/src/Parser/Parsing/TokenPos.cpp b/src/Parser/Parsing/TokenPos.cpp index fe9d9c5d..d8dcf469 100644 --- a/src/Parser/Parsing/TokenPos.cpp +++ b/src/Parser/Parsing/TokenPos.cpp @@ -1,15 +1,18 @@ #include "TokenPos.h" -const std::string TokenPos::EMPTY_FILENAME; +namespace +{ + const std::string EMPTY_FILENAME; +} TokenPos::TokenPos() : m_filename(EMPTY_FILENAME), - m_line(1), - m_column(1) + m_line(1uz), + m_column(1uz) { } -TokenPos::TokenPos(const std::string& filename, const int line, const int column) +TokenPos::TokenPos(const std::string& filename, const size_t line, const size_t column) : m_filename(filename), m_line(line), m_column(column) diff --git a/src/Parser/Parsing/TokenPos.h b/src/Parser/Parsing/TokenPos.h index 103b2dd5..7ceadd6d 100644 --- a/src/Parser/Parsing/TokenPos.h +++ b/src/Parser/Parsing/TokenPos.h @@ -5,13 +5,11 @@ class TokenPos { - static const std::string EMPTY_FILENAME; - public: - std::reference_wrapper m_filename; - int m_line; - int m_column; - TokenPos(); - TokenPos(const std::string& filename, int line, int column); + TokenPos(const std::string& filename, size_t line, size_t column); + + std::reference_wrapper m_filename; + size_t m_line; + size_t m_column; }; diff --git a/src/Utils/Utils/Arguments/ArgumentParser.cpp b/src/Utils/Utils/Arguments/ArgumentParser.cpp index 1f89a5ed..caff4ce1 100644 --- a/src/Utils/Utils/Arguments/ArgumentParser.cpp +++ b/src/Utils/Utils/Arguments/ArgumentParser.cpp @@ -42,7 +42,7 @@ bool ArgumentParser::ParseArguments(std::vector& args) m_path = args[0]; const auto argCount = args.size(); - for (unsigned argIndex = 1u; argIndex < argCount; argIndex++) + for (auto argIndex = 1uz; argIndex < argCount; argIndex++) { auto& arg = args[argIndex]; @@ -85,7 +85,7 @@ bool ArgumentParser::ParseArguments(std::vector& args) return false; } - if (m_matched_options.find(matchedOption) != m_matched_options.end()) + if (m_matched_options.contains(matchedOption)) { if (!matchedOption->m_multi_use) { @@ -106,7 +106,7 @@ bool ArgumentParser::ParseArguments(std::vector& args) } auto& parameters = m_matched_options[matchedOption]; - for (unsigned parameterIndex = 0; parameterIndex < parameterCount; parameterIndex++) + for (auto parameterIndex = 0uz; parameterIndex < parameterCount; parameterIndex++) { std::string& param = args[argIndex + parameterIndex + 1]; @@ -116,14 +116,14 @@ bool ArgumentParser::ParseArguments(std::vector& args) return false; } - parameters.push_back(param); + parameters.emplace_back(param); } argIndex += parameterCount; } else { - m_matched_arguments.push_back(arg); + m_matched_arguments.emplace_back(arg); } } diff --git a/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.cpp b/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.cpp index 2b9e99ba..aec0c366 100644 --- a/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.cpp +++ b/src/ZoneCodeGeneratorLib/Domain/Computations/MemberDeclarationModifierComputations.cpp @@ -12,18 +12,18 @@ DeclarationModifierComputations::DeclarationModifierComputations(const MemberInf m_modifier_indices(std::move(modifierIndices)) { auto combinedIndex = 0; - auto arraySizes = MemberComputations(m_information).GetArraySizes(); + const auto arraySizes = MemberComputations(m_information).GetArraySizes(); std::vector sizePerDepth(arraySizes.size()); auto currentDepthSize = 1; - for (int i = arraySizes.size(); i > 0; i--) + for (int i = static_cast(arraySizes.size()); i > 0; i--) { sizePerDepth[i - 1] = currentDepthSize; currentDepthSize *= arraySizes[i - 1]; } auto currentDepth = 0; - for (auto modifierIndex : m_modifier_indices) + for (const auto modifierIndex : m_modifier_indices) { combinedIndex += sizePerDepth[currentDepth++] * modifierIndex; } @@ -62,7 +62,7 @@ std::vector DeclarationModifierComputations::GetFollowingD if (m_modifier_indices.size() + 1 < declarationModifiers.size()) { - for (auto i = declarationModifiers.begin() + m_modifier_indices.size() + 1; i != declarationModifiers.end(); ++i) + for (auto i = declarationModifiers.begin() + m_modifier_indices.size() + 1uz; i != declarationModifiers.end(); ++i) { following.push_back(i->get()); } diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.cpp b/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.cpp index 75f6c66b..00ed3005 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.cpp @@ -1,5 +1,63 @@ #include "CommandsParserState.h" +namespace +{ + MemberInformation* GetMemberWithName(const std::string& memberName, const StructureInformation* type) + { + for (const auto& member : type->m_ordered_members) + { + if (member->m_member->m_name == memberName) + { + return member.get(); + } + } + + return nullptr; + } + + bool GetNextTypenameSeparatorPos(const std::string& typeNameValue, const size_t startPos, size_t& separatorPos) + { + const auto typeNameValueSize = typeNameValue.size(); + for (auto currentHead = startPos + 1; currentHead < typeNameValueSize; currentHead++) + { + if (typeNameValue[currentHead] == ':' && typeNameValue[currentHead - 1] == ':') + { + separatorPos = currentHead - 1; + return true; + } + } + + return false; + } + + bool ExtractMembersFromTypenameInternal(const std::string& typeNameValue, + size_t typeNameOffset, + const StructureInformation* type, + std::vector& members) + { + auto startOffset = typeNameOffset; + while (GetNextTypenameSeparatorPos(typeNameValue, typeNameOffset, typeNameOffset)) + { + auto* foundMember = GetMemberWithName(std::string(typeNameValue, startOffset, typeNameOffset - startOffset), type); + + if (foundMember == nullptr) + return false; + + members.push_back(foundMember); + type = foundMember->m_type; + typeNameOffset += 2; + startOffset = typeNameOffset; + } + + auto* foundMember = GetMemberWithName(std::string(typeNameValue, startOffset, typeNameValue.size() - startOffset), type); + if (foundMember == nullptr) + return false; + + members.push_back(foundMember); + return true; + } +} // namespace + CommandsParserState::CommandsParserState(IDataRepository* repository) : m_repository(repository), m_in_use(nullptr) @@ -36,63 +94,8 @@ void CommandsParserState::SetInUse(StructureInformation* structure) m_in_use = structure; } -MemberInformation* CommandsParserState::GetMemberWithName(const std::string& memberName, StructureInformation* type) -{ - for (const auto& member : type->m_ordered_members) - { - if (member->m_member->m_name == memberName) - { - return member.get(); - } - } - - return nullptr; -} - -bool CommandsParserState::GetNextTypenameSeparatorPos(const std::string& typeNameValue, const unsigned startPos, unsigned& separatorPos) -{ - const auto typeNameValueSize = typeNameValue.size(); - for (auto currentHead = startPos + 1; currentHead < typeNameValueSize; currentHead++) - { - if (typeNameValue[currentHead] == ':' && typeNameValue[currentHead - 1] == ':') - { - separatorPos = currentHead - 1; - return true; - } - } - - return false; -} - -bool CommandsParserState::ExtractMembersFromTypenameInternal(const std::string& typeNameValue, - unsigned typeNameOffset, - StructureInformation* type, - std::vector& members) -{ - auto startOffset = typeNameOffset; - while (GetNextTypenameSeparatorPos(typeNameValue, typeNameOffset, typeNameOffset)) - { - auto* foundMember = GetMemberWithName(std::string(typeNameValue, startOffset, typeNameOffset - startOffset), type); - - if (foundMember == nullptr) - return false; - - members.push_back(foundMember); - type = foundMember->m_type; - typeNameOffset += 2; - startOffset = typeNameOffset; - } - - auto* foundMember = GetMemberWithName(std::string(typeNameValue, startOffset, typeNameValue.size() - startOffset), type); - if (foundMember == nullptr) - return false; - - members.push_back(foundMember); - return true; -} - bool CommandsParserState::GetMembersFromTypename(const std::string& typeNameValue, - StructureInformation* baseType, + const StructureInformation* baseType, std::vector& members) const { return m_in_use != nullptr && ExtractMembersFromTypenameInternal(typeNameValue, 0, m_in_use, members) @@ -114,7 +117,7 @@ bool CommandsParserState::GetTypenameAndMembersFromTypename(const std::string& t } DataDefinition* foundDefinition = nullptr; - unsigned currentSeparatorPos = 0; + auto currentSeparatorPos = 0uz; while (GetNextTypenameSeparatorPos(typeNameValue, currentSeparatorPos, currentSeparatorPos)) { std::string currentTypename(typeNameValue, 0, currentSeparatorPos); @@ -134,7 +137,7 @@ bool CommandsParserState::GetTypenameAndMembersFromTypename(const std::string& t if (foundDefinition == nullptr) return false; - auto* definitionWithMembers = dynamic_cast(foundDefinition); + const auto* definitionWithMembers = dynamic_cast(foundDefinition); if (definitionWithMembers == nullptr) return false; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.h b/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.h index be50ef18..a38b322f 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Impl/CommandsParserState.h @@ -19,17 +19,10 @@ public: [[nodiscard]] StructureInformation* GetInUse() const; void SetInUse(StructureInformation* structure); - bool GetMembersFromTypename(const std::string& typeNameValue, StructureInformation* baseType, std::vector& members) const; + bool GetMembersFromTypename(const std::string& typeNameValue, const StructureInformation* baseType, std::vector& members) const; bool GetTypenameAndMembersFromTypename(const std::string& typeNameValue, StructureInformation*& structure, std::vector& members) const; private: - static MemberInformation* GetMemberWithName(const std::string& memberName, StructureInformation* type); - static bool GetNextTypenameSeparatorPos(const std::string& typeNameValue, unsigned startPos, unsigned& separatorPos); - static bool ExtractMembersFromTypenameInternal(const std::string& typeNameValue, - unsigned typeNameOffset, - StructureInformation* type, - std::vector& members); - IDataRepository* m_repository; StructureInformation* m_in_use; }; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Matcher/CommandsCommonMatchers.cpp b/src/ZoneCodeGeneratorLib/Parsing/Commands/Matcher/CommandsCommonMatchers.cpp index 3bc815df..8bed3923 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Matcher/CommandsCommonMatchers.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Matcher/CommandsCommonMatchers.cpp @@ -6,6 +6,7 @@ #include "Domain/Evaluation/Operation.h" #include +#include #include #include #include @@ -353,7 +354,7 @@ std::unique_ptr currentType = nullptr; std::vector> operands; - std::list> operators; + std::list> operators; while (true) { @@ -384,7 +385,7 @@ std::unique_ptr } operators.sort( - [](const std::pair& p1, const std::pair& p2) + [](const std::pair& p1, const std::pair& p2) { if (p1.second->m_precedence != p2.second->m_precedence) return p1.second->m_precedence > p2.second->m_precedence; @@ -402,7 +403,7 @@ std::unique_ptr operators.pop_back(); - for (auto& [opIndex, _] : operators) + for (auto& opIndex : operators | std::views::keys) { if (opIndex > operatorIndex) opIndex--; diff --git a/test/ParserTestUtils/Parsing/Mock/MockLexer.h b/test/ParserTestUtils/Parsing/Mock/MockLexer.h index ae484456..f48c303a 100644 --- a/test/ParserTestUtils/Parsing/Mock/MockLexer.h +++ b/test/ParserTestUtils/Parsing/Mock/MockLexer.h @@ -3,18 +3,12 @@ #include "Parsing/ILexer.h" #include "Utils/ClassUtils.h" +#include #include #include -template class MockLexer final : public ILexer +template TokenType> class MockLexer final : public ILexer { - // TokenType must inherit IParserValue - static_assert(std::is_base_of::value); - - std::vector m_tokens; - TokenType m_eof; - size_t m_pop_count; - public: MockLexer(std::initializer_list> tokens, TokenType eof) : m_tokens(std::make_move_iterator(tokens.begin()), std::make_move_iterator(tokens.end())), @@ -36,7 +30,7 @@ public: MockLexer& operator=(const MockLexer& other) = delete; MockLexer& operator=(MockLexer&& other) noexcept = default; - const TokenType& GetToken(const unsigned index) override + const TokenType& GetToken(const size_t index) override { const auto absoluteIndex = m_pop_count + index; if (absoluteIndex < m_tokens.size()) @@ -45,10 +39,10 @@ public: return m_eof; } - void PopTokens(const int amount) override + void PopTokens(const size_t amount) override { assert(amount >= 0); - m_pop_count += static_cast(amount); + m_pop_count += amount; } bool IsEof() override @@ -70,4 +64,9 @@ public: { return ParserLine(); } + +private: + std::vector m_tokens; + TokenType m_eof; + size_t m_pop_count; };