diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.cpp new file mode 100644 index 00000000..2b9edf0a --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.cpp @@ -0,0 +1,31 @@ +#include "HeaderBlockEnum.h" + +#include "Parsing/Header/Sequence/SequenceCloseBlock.h" +#include "Parsing/Header/Sequence/SequenceEnumMember.h" + +HeaderBlockType HeaderBlockEnum::GetType() +{ + return HeaderBlockType::UNION; +} + +const std::vector& HeaderBlockEnum::GetTestsForBlock() +{ + static std::vector tests({ + new SequenceCloseBlock(), + new SequenceEnumMember() + }); + + return tests; +} + +void HeaderBlockEnum::OnOpen() +{ +} + +void HeaderBlockEnum::OnClose() +{ +} + +void HeaderBlockEnum::OnChildBlockClose(IHeaderBlock* block) +{ +} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.h new file mode 100644 index 00000000..ec9dd1c9 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockEnum.h @@ -0,0 +1,13 @@ +#pragma once + +#include "IHeaderBlock.h" + +class HeaderBlockEnum final : public IHeaderBlock +{ +public: + HeaderBlockType GetType() override; + const std::vector& GetTestsForBlock() override; + void OnOpen() override; + void OnClose() override; + void OnChildBlockClose(IHeaderBlock* block) override; +}; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNamespace.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNamespace.cpp new file mode 100644 index 00000000..eba5f3ea --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNamespace.cpp @@ -0,0 +1,41 @@ +#include "HeaderBlockNamespace.h" + +#include "Parsing/Header/Sequence/SequenceCloseBlock.h" +#include "Parsing/Header/Sequence/SequenceEnum.h" +#include "Parsing/Header/Sequence/SequenceForwardDecl.h" +#include "Parsing/Header/Sequence/SequenceNamespace.h" +#include "Parsing/Header/Sequence/SequenceStruct.h" +#include "Parsing/Header/Sequence/SequenceTypedef.h" +#include "Parsing/Header/Sequence/SequenceUnion.h" + +HeaderBlockType HeaderBlockNamespace::GetType() +{ + return HeaderBlockType::NAMESPACE; +} + +const std::vector& HeaderBlockNamespace::GetTestsForBlock() +{ + static std::vector tests({ + new SequenceCloseBlock(), + new SequenceEnum(), + new SequenceForwardDecl(), + new SequenceNamespace(), + new SequenceStruct(), + new SequenceTypedef(), + new SequenceUnion() + }); + + return tests; +} + +void HeaderBlockNamespace::OnOpen() +{ +} + +void HeaderBlockNamespace::OnClose() +{ +} + +void HeaderBlockNamespace::OnChildBlockClose(IHeaderBlock* block) +{ +} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNamespace.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNamespace.h new file mode 100644 index 00000000..9683d937 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNamespace.h @@ -0,0 +1,13 @@ +#pragma once + +#include "IHeaderBlock.h" + +class HeaderBlockNamespace final : public IHeaderBlock +{ +public: + HeaderBlockType GetType() override; + const std::vector& GetTestsForBlock() override; + void OnOpen() override; + void OnClose() override; + void OnChildBlockClose(IHeaderBlock* block) override; +}; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNone.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNone.cpp new file mode 100644 index 00000000..aba0e2a9 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNone.cpp @@ -0,0 +1,39 @@ +#include "HeaderBlockNone.h" + +#include "Parsing/Header/Sequence/SequenceEnum.h" +#include "Parsing/Header/Sequence/SequenceForwardDecl.h" +#include "Parsing/Header/Sequence/SequenceNamespace.h" +#include "Parsing/Header/Sequence/SequenceStruct.h" +#include "Parsing/Header/Sequence/SequenceTypedef.h" +#include "Parsing/Header/Sequence/SequenceUnion.h" + +HeaderBlockType HeaderBlockNone::GetType() +{ + return HeaderBlockType::NONE; +} + +const std::vector& HeaderBlockNone::GetTestsForBlock() +{ + static std::vector tests({ + new SequenceEnum(), + new SequenceForwardDecl(), + new SequenceNamespace(), + new SequenceStruct(), + new SequenceTypedef(), + new SequenceUnion() + }); + + return tests; +} + +void HeaderBlockNone::OnOpen() +{ +} + +void HeaderBlockNone::OnClose() +{ +} + +void HeaderBlockNone::OnChildBlockClose(IHeaderBlock* block) +{ +} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNone.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNone.h new file mode 100644 index 00000000..ad0bf7fe --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockNone.h @@ -0,0 +1,13 @@ +#pragma once + +#include "IHeaderBlock.h" + +class HeaderBlockNone final : public IHeaderBlock +{ +public: + HeaderBlockType GetType() override; + const std::vector& GetTestsForBlock() override; + void OnOpen() override; + void OnClose() override; + void OnChildBlockClose(IHeaderBlock* block) override; +}; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp new file mode 100644 index 00000000..8a024052 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.cpp @@ -0,0 +1,37 @@ +#include "HeaderBlockStruct.h" + +#include "Parsing/Header/Sequence/SequenceCloseBlock.h" +#include "Parsing/Header/Sequence/SequenceEnum.h" +#include "Parsing/Header/Sequence/SequenceStruct.h" +#include "Parsing/Header/Sequence/SequenceUnion.h" +#include "Parsing/Header/Sequence/SequenceVariable.h" + +HeaderBlockType HeaderBlockStruct::GetType() +{ + return HeaderBlockType::STRUCT; +} + +const std::vector& HeaderBlockStruct::GetTestsForBlock() +{ + static std::vector tests({ + new SequenceCloseBlock(), + new SequenceEnum(), + new SequenceStruct(), + new SequenceUnion(), + new SequenceVariable() + }); + + return tests; +} + +void HeaderBlockStruct::OnOpen() +{ +} + +void HeaderBlockStruct::OnClose() +{ +} + +void HeaderBlockStruct::OnChildBlockClose(IHeaderBlock* block) +{ +} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.h new file mode 100644 index 00000000..933533e1 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockStruct.h @@ -0,0 +1,13 @@ +#pragma once + +#include "IHeaderBlock.h" + +class HeaderBlockStruct final : public IHeaderBlock +{ +public: + HeaderBlockType GetType() override; + const std::vector& GetTestsForBlock() override; + void OnOpen() override; + void OnClose() override; + void OnChildBlockClose(IHeaderBlock* block) override; +}; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp new file mode 100644 index 00000000..7b8a52a8 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.cpp @@ -0,0 +1,37 @@ +#include "HeaderBlockUnion.h" + +#include "Parsing/Header/Sequence/SequenceCloseBlock.h" +#include "Parsing/Header/Sequence/SequenceEnum.h" +#include "Parsing/Header/Sequence/SequenceStruct.h" +#include "Parsing/Header/Sequence/SequenceUnion.h" +#include "Parsing/Header/Sequence/SequenceVariable.h" + +HeaderBlockType HeaderBlockUnion::GetType() +{ + return HeaderBlockType::UNION; +} + +const std::vector& HeaderBlockUnion::GetTestsForBlock() +{ + static std::vector tests({ + new SequenceCloseBlock(), + new SequenceEnum(), + new SequenceStruct(), + new SequenceUnion(), + new SequenceVariable() + }); + + return tests; +} + +void HeaderBlockUnion::OnOpen() +{ +} + +void HeaderBlockUnion::OnClose() +{ +} + +void HeaderBlockUnion::OnChildBlockClose(IHeaderBlock* block) +{ +} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.h new file mode 100644 index 00000000..912e85e0 --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/HeaderBlockUnion.h @@ -0,0 +1,13 @@ +#pragma once + +#include "IHeaderBlock.h" + +class HeaderBlockUnion final : public IHeaderBlock +{ +public: + HeaderBlockType GetType() override; + const std::vector& GetTestsForBlock() override; + void OnOpen() override; + void OnClose() override; + void OnChildBlockClose(IHeaderBlock* block) override; +}; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Block/IHeaderBlock.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/IHeaderBlock.h new file mode 100644 index 00000000..b2f2c0af --- /dev/null +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Block/IHeaderBlock.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +#include "Parsing/Sequence/AbstractSequence.h" +#include "Parsing/Header/Impl/HeaderParserState.h" + +enum class HeaderBlockType +{ + NONE, + NAMESPACE, + ENUM, + STRUCT, + UNION +}; + +class HeaderParserValue; +class HeaderParserState; +class IHeaderBlock +{ +public: + typedef AbstractSequence sequence_t; + + IHeaderBlock() = default; + virtual ~IHeaderBlock() = default; + IHeaderBlock(const IHeaderBlock& other) = default; + IHeaderBlock(IHeaderBlock&& other) noexcept = default; + IHeaderBlock& operator=(const IHeaderBlock& other) = default; + IHeaderBlock& operator=(IHeaderBlock&& other) noexcept = default; + + virtual HeaderBlockType GetType() = 0; + + virtual const std::vector& GetTestsForBlock() = 0; + + virtual void OnOpen() = 0; + virtual void OnClose() = 0; + virtual void OnChildBlockClose(IHeaderBlock* block) = 0; +}; \ No newline at end of file diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderLexer.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderLexer.cpp index 7258518a..b2a70215 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderLexer.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderLexer.cpp @@ -11,12 +11,17 @@ void HeaderLexer::PrepareKeywords() m_keywords["__declspec"] = HeaderParserValueType::DECLSPEC; m_keywords["align"] = HeaderParserValueType::ALIGN; m_keywords["alignas"] = HeaderParserValueType::ALIGNAS; + m_keywords["char"] = HeaderParserValueType::CHAR; m_keywords["const"] = HeaderParserValueType::CONST; m_keywords["enum"] = HeaderParserValueType::ENUM; + m_keywords["int"] = HeaderParserValueType::INT; + m_keywords["long"] = HeaderParserValueType::LONG; m_keywords["namespace"] = HeaderParserValueType::NAMESPACE; + m_keywords["short"] = HeaderParserValueType::SHORT; m_keywords["struct"] = HeaderParserValueType::STRUCT; m_keywords["typedef"] = HeaderParserValueType::TYPEDEF; m_keywords["union"] = HeaderParserValueType::UNION; + m_keywords["unsigned"] = HeaderParserValueType::UNSIGNED; } HeaderParserValue HeaderLexer::GetNextToken() diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.cpp index 8e3644e5..21711762 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.cpp @@ -7,11 +7,9 @@ HeaderParser::HeaderParser(HeaderLexer* lexer, IDataRepository* targetRepository m_repository(targetRepository) { auto sequenceNamespace = std::make_unique(); - m_normal_tests.push_back(sequenceNamespace.get()); - m_tests.emplace_back(std::move(sequenceNamespace)); } const std::vector& HeaderParser::GetTestsForState() { - return m_normal_tests; + return m_state->GetBlock()->GetTestsForBlock(); } diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.h index f7bbc5f1..6ae208c6 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParser.h @@ -9,9 +9,6 @@ class HeaderParser final : public AbstractParser> m_tests; - std::vector m_normal_tests; - protected: const std::vector& GetTestsForState() override; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.cpp index e69de29b..46fa46ef 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.cpp @@ -0,0 +1,13 @@ +#include "HeaderParserState.h" + +#include "Parsing/Header/Block/HeaderBlockNone.h" + +HeaderParserState::HeaderParserState() +{ + m_blocks.push(std::make_unique()); +} + +IHeaderBlock* HeaderParserState::GetBlock() const +{ + return m_blocks.top().get(); +} diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.h index 12aafd80..bd116a20 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserState.h @@ -1,7 +1,18 @@ #pragma once +#include +#include + +#include "Utils/ClassUtils.h" +#include "Parsing/Header/Block/IHeaderBlock.h" + +class IHeaderBlock; class HeaderParserState { -public: + std::stack> m_blocks; -}; \ No newline at end of file +public: + HeaderParserState(); + + _NODISCARD IHeaderBlock* GetBlock() const; +}; diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserValue.h b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserValue.h index 427ef5fa..d707c677 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserValue.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderParserValue.h @@ -2,7 +2,6 @@ #include - #include "Parsing/IParserValue.h" #include "Utils/ClassUtils.h" #include "Parsing/TokenPos.h" @@ -32,6 +31,15 @@ enum class HeaderParserValueType STRING, IDENTIFIER, + // Built-in types + BUILT_IN_FIRST, + UNSIGNED = BUILT_IN_FIRST, + CHAR, + SHORT, + INT, + LONG, + BUILT_IN_LAST = LONG, + // Keywords DECLSPEC, ALIGN, diff --git a/src/ZoneCodeGeneratorLib/Parsing/Header/Matcher/HeaderCommonMatchers.cpp b/src/ZoneCodeGeneratorLib/Parsing/Header/Matcher/HeaderCommonMatchers.cpp index d056b1a7..538f3762 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Header/Matcher/HeaderCommonMatchers.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Header/Matcher/HeaderCommonMatchers.cpp @@ -35,7 +35,7 @@ std::unique_ptr HeaderCommonMatchers::ArrayDef( create.Char(']') }).Transform([](HeaderMatcherFactory::token_list_t& values) { - if(values[1].get().m_type == HeaderParserValueType::INTEGER) + if (values[1].get().m_type == HeaderParserValueType::INTEGER) return HeaderParserValue::Integer(values[1].get().GetPos(), values[1].get().IntegerValue()); return HeaderParserValue::Identifier(values[1].get().GetPos(), new std::string(values[1].get().IdentifierValue())); @@ -44,23 +44,62 @@ std::unique_ptr HeaderCommonMatchers::ArrayDef( std::unique_ptr HeaderCommonMatchers::Typename(const supplier_t* labelSupplier) { + static constexpr const char* BUILT_IN_TYPE_NAMES[] + { + "unsigned", + "char", + "short", + "int", + "long" + }; + static_assert(_countof(BUILT_IN_TYPE_NAMES) == static_cast(HeaderParserValueType::BUILT_IN_LAST) - static_cast(HeaderParserValueType::BUILT_IN_FIRST) + 1); + const HeaderMatcherFactory create(labelSupplier); - return create.And({ - create.Identifier(), - create.OptionalLoop(create.And({ - create.Char(':'), - create.Char(':'), - create.Identifier() - })) - }).Transform([](HeaderMatcherFactory::token_list_t& values) - { - std::ostringstream str; - str << values[0].get().IdentifierValue(); + return create.Or({ + create.And({ + create.Optional(create.Type(HeaderParserValueType::UNSIGNED)), + create.Or({ + create.Type(HeaderParserValueType::CHAR), + create.Type(HeaderParserValueType::SHORT), + create.Type(HeaderParserValueType::INT), + create.And({ + create.Type(HeaderParserValueType::LONG), + create.Optional(create.Type(HeaderParserValueType::LONG)) + }) + }) + }).Transform([](HeaderMatcherFactory::token_list_t& values) + { + std::ostringstream str; + auto first = false; - for (auto i = 3u; i < values.size(); i += 3) - str << "::" << values[i].get().IdentifierValue(); + for(const auto& token : values) + { + if (first) + first = false; + else + str << " "; + str << BUILT_IN_TYPE_NAMES[static_cast(token.get().m_type) - static_cast(HeaderParserValueType::BUILT_IN_FIRST)]; + } - return HeaderParserValue::TypeName(values[0].get().GetPos(), new std::string(str.str())); - }).Build(); + return HeaderParserValue::TypeName(values[0].get().GetPos(), new std::string(str.str())); + }), + create.And({ + create.Identifier(), + create.OptionalLoop(create.And({ + create.Char(':'), + create.Char(':'), + create.Identifier() + })) + }).Transform([](HeaderMatcherFactory::token_list_t& values) + { + std::ostringstream str; + str << values[0].get().IdentifierValue(); + + for (auto i = 3u; i < values.size(); i += 3) + str << "::" << values[i].get().IdentifierValue(); + + return HeaderParserValue::TypeName(values[0].get().GetPos(), new std::string(str.str())); + }) + }); }