diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionEntry.cpp b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionEntry.cpp new file mode 100644 index 00000000..6bc257c9 --- /dev/null +++ b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionEntry.cpp @@ -0,0 +1,23 @@ +#include "SequenceZoneDefinitionEntry.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceZoneDefinitionEntry::SequenceZoneDefinitionEntry() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Identifier().Capture(CAPTURE_TYPE_NAME), + create.Char(','), + create.Optional(create.Char(',').Tag(TAG_REFERENCE)), + create.Identifier().Capture(CAPTURE_ASSET_NAME) + }); +} + +void SequenceZoneDefinitionEntry::ProcessMatch(ZoneDefinition* state, SequenceResult& result) const +{ + state->m_assets.emplace_back( + result.NextCapture(CAPTURE_TYPE_NAME).IdentifierValue(), + result.NextCapture(CAPTURE_ASSET_NAME).IdentifierValue(), + result.NextTag() == TAG_REFERENCE); +} diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionEntry.h b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionEntry.h new file mode 100644 index 00000000..34df7a7f --- /dev/null +++ b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionEntry.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Parsing/ZoneDefinition/ZoneDefinitionParser.h" + +class SequenceZoneDefinitionEntry final : public ZoneDefinitionParser::sequence_t +{ + static constexpr auto TAG_REFERENCE = 1; + + static constexpr auto CAPTURE_TYPE_NAME = 1; + static constexpr auto CAPTURE_ASSET_NAME = 2; + +protected: + void ProcessMatch(ZoneDefinition* state, SequenceResult& result) const override; + +public: + SequenceZoneDefinitionEntry(); +}; diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionMetaData.cpp b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionMetaData.cpp new file mode 100644 index 00000000..e4e296bd --- /dev/null +++ b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionMetaData.cpp @@ -0,0 +1,20 @@ +#include "SequenceZoneDefinitionMetaData.h" + +#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" + +SequenceZoneDefinitionMetaData::SequenceZoneDefinitionMetaData() +{ + const SimpleMatcherFactory create(this); + + AddMatchers({ + create.Char('>'), + create.Identifier().Capture(CAPTURE_KEY), + create.Char(','), + create.Identifier().Capture(CAPTURE_VALUE) + }); +} + +void SequenceZoneDefinitionMetaData::ProcessMatch(ZoneDefinition* state, SequenceResult& result) const +{ + state->m_metadata[result.NextCapture(CAPTURE_KEY).IdentifierValue()] = result.NextCapture(CAPTURE_VALUE).IdentifierValue(); +} diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionMetaData.h b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionMetaData.h new file mode 100644 index 00000000..00c19257 --- /dev/null +++ b/src/ZoneCommon/Parsing/ZoneDefinition/Sequence/SequenceZoneDefinitionMetaData.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Parsing/ZoneDefinition/ZoneDefinitionParser.h" + +class SequenceZoneDefinitionMetaData final : public ZoneDefinitionParser::sequence_t +{ + static constexpr auto CAPTURE_KEY = 1; + static constexpr auto CAPTURE_VALUE = 2; + +protected: + void ProcessMatch(ZoneDefinition* state, SequenceResult& result) const override; + +public: + SequenceZoneDefinitionMetaData(); +}; diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.cpp b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.cpp new file mode 100644 index 00000000..6a5a9d0f --- /dev/null +++ b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.cpp @@ -0,0 +1,24 @@ +#include "ZoneDefinitionParser.h" + +#include "Sequence/SequenceZoneDefinitionEntry.h" +#include "Sequence/SequenceZoneDefinitionMetaData.h" + +ZoneDefinitionParser::ZoneDefinitionParser(SimpleLexer* lexer) + : AbstractParser(lexer, std::make_unique()) +{ +} + +const std::vector::sequence_t*>& ZoneDefinitionParser::GetTestsForState() +{ + static std::vector tests({ + new SequenceZoneDefinitionMetaData(), + new SequenceZoneDefinitionEntry() + }); + + return tests; +} + +std::unique_ptr ZoneDefinitionParser::GetParsedValue() +{ + return std::move(m_state); +} diff --git a/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.h b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.h new file mode 100644 index 00000000..911fc066 --- /dev/null +++ b/src/ZoneCommon/Parsing/ZoneDefinition/ZoneDefinitionParser.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Parsing/Simple/SimpleLexer.h" +#include "Parsing/Simple/SimpleParserValue.h" +#include "Parsing/Impl/AbstractParser.h" +#include "Zone/Definition/ZoneDefinition.h" + +class ZoneDefinitionParser final : public AbstractParser +{ +protected: + const std::vector& GetTestsForState() override; + +public: + explicit ZoneDefinitionParser(SimpleLexer* lexer); + std::unique_ptr GetParsedValue(); +}; diff --git a/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.cpp b/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.cpp index 20ea1760..dfae4e99 100644 --- a/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.cpp +++ b/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.cpp @@ -1,13 +1,62 @@ #include "ZoneDefinitionStream.h" -ZoneDefinitionInputStream::ZoneDefinitionInputStream(std::istream& stream) - : m_stream(stream) +#include + +#include "Parsing/Impl/ParserInputStream.h" +#include + +#include "Parsing/Impl/DefinesStreamProxy.h" +#include "Parsing/Simple/SimpleLexer.h" +#include "Parsing/ZoneDefinition/ZoneDefinitionParser.h" + +ZoneDefinitionInputStream::ZoneDefinitionInputStream(std::istream& stream, std::string fileName, bool verbose) + : m_file_name(std::move(fileName)), + m_verbose(verbose), + m_stream(nullptr) { + OpenBaseStream(stream); + SetupStreamProxies(); + m_stream = m_open_streams.back().get(); +} + +bool ZoneDefinitionInputStream::OpenBaseStream(std::istream& stream) +{ + m_open_streams.emplace_back(std::make_unique(stream, m_file_name)); + return true; +} + +void ZoneDefinitionInputStream::SetupStreamProxies() +{ + m_open_streams.emplace_back(std::make_unique(m_open_streams.back().get())); + auto definesProxy = std::make_unique(m_open_streams.back().get()); + definesProxy->AddDefine(DefinesStreamProxy::Define(ZONE_CODE_GENERATOR_DEFINE_NAME, ZONE_CODE_GENERATOR_DEFINE_VALUE)); + m_open_streams.emplace_back(std::move(definesProxy)); + + m_stream = m_open_streams.back().get(); } std::unique_ptr ZoneDefinitionInputStream::ReadDefinition() { - return nullptr; + if (m_verbose) + { + std::cout << "Reading zone definition file: " << m_file_name << std::endl; + } + + const auto lexer = std::make_unique(m_stream); + const auto parser = std::make_unique(lexer.get()); + + const auto start = std::chrono::steady_clock::now(); + std::unique_ptr definition; + if (parser->Parse()) + definition = parser->GetParsedValue(); + const auto end = std::chrono::steady_clock::now(); + + if (m_verbose) + { + std::cout << "Processing zone definition took " << std::chrono::duration_cast(end - start).count() << "ms" << std::endl; + } + + return std::move(definition); } ZoneDefinitionOutputStream::ZoneDefinitionOutputStream(std::ostream& stream) diff --git a/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.h b/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.h index 01ff04a4..54441a47 100644 --- a/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.h +++ b/src/ZoneCommon/Zone/Definition/ZoneDefinitionStream.h @@ -3,13 +3,23 @@ #include #include "ZoneDefinition.h" +#include "Parsing/IParserLineStream.h" class ZoneDefinitionInputStream { - std::istream& m_stream; + static constexpr const char* ZONE_CODE_GENERATOR_DEFINE_NAME = "__zonecodegenerator"; + static constexpr const char* ZONE_CODE_GENERATOR_DEFINE_VALUE = "1"; + + std::string m_file_name; + bool m_verbose; + IParserLineStream* m_stream; + std::vector> m_open_streams; + + bool OpenBaseStream(std::istream& stream); + void SetupStreamProxies(); public: - explicit ZoneDefinitionInputStream(std::istream& stream); + ZoneDefinitionInputStream(std::istream& stream, std::string fileName, bool verbose); std::unique_ptr ReadDefinition(); };