diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.cpp index 50e724ea..1da228ed 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.cpp @@ -11,7 +11,7 @@ HeaderBlockType HeaderBlockEnum::GetType() const std::vector& HeaderBlockEnum::GetTestsForBlock() { static std::vector tests({ - new SequenceCloseBlock(), + new SequenceCloseBlock(true), new SequenceEnumMember() }); @@ -29,3 +29,8 @@ void HeaderBlockEnum::OnClose(HeaderParserState* state) void HeaderBlockEnum::OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) { } + +void HeaderBlockEnum::SetVariableName(std::string name) +{ + m_variable_name = std::move(name); +} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.h index d6a0a2c2..378bdb7b 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.h @@ -1,13 +1,18 @@ #pragma once #include "IHeaderBlock.h" +#include "IHeaderBlockVariableDefining.h" -class HeaderBlockEnum final : public IHeaderBlock +class HeaderBlockEnum final : public IHeaderBlock, public IHeaderBlockVariableDefining { + std::string m_variable_name; + public: HeaderBlockType GetType() override; const std::vector& GetTestsForBlock() override; void OnOpen(HeaderParserState* state) override; void OnClose(HeaderParserState* state) override; void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override; + + void SetVariableName(std::string name) override; }; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNamespace.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNamespace.cpp index 126c8376..79b7591a 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNamespace.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNamespace.cpp @@ -21,7 +21,7 @@ HeaderBlockType HeaderBlockNamespace::GetType() const std::vector& HeaderBlockNamespace::GetTestsForBlock() { static std::vector tests({ - new SequenceCloseBlock(), + new SequenceCloseBlock(false), new SequenceEnum(), new SequenceForwardDecl(), new SequenceNamespace(), diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp index c980be93..a41ec287 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp @@ -14,7 +14,7 @@ HeaderBlockType HeaderBlockStruct::GetType() const std::vector& HeaderBlockStruct::GetTestsForBlock() { static std::vector tests({ - new SequenceCloseBlock(), + new SequenceCloseBlock(true), new SequenceEnum(), new SequenceStruct(), new SequenceUnion(), @@ -35,3 +35,8 @@ void HeaderBlockStruct::OnClose(HeaderParserState* state) void HeaderBlockStruct::OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) { } + +void HeaderBlockStruct::SetVariableName(std::string name) +{ + m_variable_name = std::move(name); +} \ No newline at end of file diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.h index 40cd549d..9c9d1349 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.h @@ -1,13 +1,18 @@ #pragma once #include "IHeaderBlock.h" +#include "IHeaderBlockVariableDefining.h" -class HeaderBlockStruct final : public IHeaderBlock +class HeaderBlockStruct final : public IHeaderBlock, public IHeaderBlockVariableDefining { + std::string m_variable_name; + public: HeaderBlockType GetType() override; const std::vector& GetTestsForBlock() override; void OnOpen(HeaderParserState* state) override; void OnClose(HeaderParserState* state) override; void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override; + + void SetVariableName(std::string name) override; }; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp index 67c01964..b70a88c1 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp @@ -14,7 +14,7 @@ HeaderBlockType HeaderBlockUnion::GetType() const std::vector& HeaderBlockUnion::GetTestsForBlock() { static std::vector tests({ - new SequenceCloseBlock(), + new SequenceCloseBlock(true), new SequenceEnum(), new SequenceStruct(), new SequenceUnion(), @@ -35,3 +35,8 @@ void HeaderBlockUnion::OnClose(HeaderParserState* state) void HeaderBlockUnion::OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) { } + +void HeaderBlockUnion::SetVariableName(std::string name) +{ + m_variable_name = std::move(name); +} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.h index d971b3fb..dc83c1a8 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.h @@ -1,13 +1,18 @@ #pragma once #include "IHeaderBlock.h" +#include "IHeaderBlockVariableDefining.h" -class HeaderBlockUnion final : public IHeaderBlock +class HeaderBlockUnion final : public IHeaderBlock, public IHeaderBlockVariableDefining { + std::string m_variable_name; + public: HeaderBlockType GetType() override; const std::vector& GetTestsForBlock() override; void OnOpen(HeaderParserState* state) override; void OnClose(HeaderParserState* state) override; void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override; + + void SetVariableName(std::string name) override; }; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/IHeaderBlockVariableDefining.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/IHeaderBlockVariableDefining.h new file mode 100644 index 00000000..f727af73 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/IHeaderBlockVariableDefining.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +class IHeaderBlockVariableDefining +{ +public: + IHeaderBlockVariableDefining() = default; + virtual ~IHeaderBlockVariableDefining() = default; + IHeaderBlockVariableDefining(const IHeaderBlockVariableDefining& other) = default; + IHeaderBlockVariableDefining(IHeaderBlockVariableDefining&& other) noexcept = default; + IHeaderBlockVariableDefining& operator=(const IHeaderBlockVariableDefining& other) = default; + IHeaderBlockVariableDefining& operator=(IHeaderBlockVariableDefining&& other) noexcept = default; + + virtual void SetVariableName(std::string name) = 0; +}; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceCloseBlock.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceCloseBlock.cpp index bcf718fd..789fd50d 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceCloseBlock.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceCloseBlock.cpp @@ -1,14 +1,16 @@ #include "SequenceCloseBlock.h" +#include "Parsing/Header/Block/IHeaderBlockVariableDefining.h" #include "Parsing/Header/Matcher/HeaderMatcherFactory.h" #include "Parsing/Header/Matcher/HeaderCommonMatchers.h" -SequenceCloseBlock::SequenceCloseBlock() +SequenceCloseBlock::SequenceCloseBlock(const bool semicolonRequired) + : m_semicolon_required(semicolonRequired) { const HeaderMatcherFactory create(this); AddMatchers({ - create.Char('}'), + create.Char('}').Capture(CAPTURE_CLOSING_PARENTHESIS), create.Optional(create.And({ create.Optional(create.Identifier().Capture(CAPTURE_NAME)), create.Char(';').Tag(TAG_SEMICOLON) @@ -18,6 +20,27 @@ SequenceCloseBlock::SequenceCloseBlock() void SequenceCloseBlock::ProcessMatch(HeaderParserState* state, SequenceResult& result) const { - // TODO: Set variable name to last block + if (result.NextTag() == TAG_SEMICOLON) + { + if(!m_semicolon_required) + throw ParsingException(result.NextCapture(CAPTURE_CLOSING_PARENTHESIS).GetPos(), "Block should not be closed with semicolon"); + } + else + { + if (m_semicolon_required) + throw ParsingException(result.NextCapture(CAPTURE_CLOSING_PARENTHESIS).GetPos(), "Block must be closed with semicolon"); + } + + if (result.HasNextCapture(CAPTURE_NAME)) + { + auto* variableDefiningBlock = dynamic_cast(state->GetBlock()); + const auto& name = result.NextCapture(CAPTURE_NAME); + + if (variableDefiningBlock == nullptr) + throw ParsingException(name.GetPos(), "Block does not support holding names."); + + variableDefiningBlock->SetVariableName(name.IdentifierValue()); + } + state->PopBlock(); } diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceCloseBlock.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceCloseBlock.h index d5523aad..1376dccc 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceCloseBlock.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Sequence/SequenceCloseBlock.h @@ -10,10 +10,13 @@ class SequenceCloseBlock final : public HeaderParser::sequence_t static constexpr auto TAG_SEMICOLON = 1; static constexpr auto CAPTURE_NAME = 1; + static constexpr auto CAPTURE_CLOSING_PARENTHESIS = 2; + + bool m_semicolon_required; protected: void ProcessMatch(HeaderParserState* state, SequenceResult& result) const override; public: - SequenceCloseBlock(); + explicit SequenceCloseBlock(bool semicolonRequired); }; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Impl/AbstractParser.h b/src/ZoneCodeGeneratorLib/Parsing/Impl/AbstractParser.h index 011a6b99..37430bcf 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Impl/AbstractParser.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Impl/AbstractParser.h @@ -30,7 +30,7 @@ protected: virtual const std::vector& GetTestsForState() = 0; public: - virtual ~AbstractParser() = default; + virtual ~AbstractParser() override = default; AbstractParser(const AbstractParser& other) = default; AbstractParser(AbstractParser&& other) noexcept = default; AbstractParser& operator=(const AbstractParser& other) = default; @@ -77,7 +77,18 @@ public: } catch (const ParsingException& e) { - std::cout << "Error: " << e.FullMessage() << std::endl; + const auto pos = e.Position(); + const auto line = m_lexer->GetLineForPos(pos); + + if (!line.IsEof()) + { + std::cout << "Error: " << e.FullMessage() << "\n" << line.m_line.substr(pos.m_column - 1) << std::endl; + } + else + { + std::cout << "Error: " << e.FullMessage() << std::endl; + } + return false; }