From b93707dfe5b1b3a3d2e9d9a76b0eaee1c02ddde3 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 13 Aug 2022 21:13:07 +0200 Subject: [PATCH] Correctly parse state map default case --- .../StateMap/Parsing/StateMapParser.cpp | 28 +++++++++++++++---- .../StateMap/StateMapDefinition.cpp | 6 ++++ src/ObjLoading/StateMap/StateMapDefinition.h | 6 +++- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/ObjLoading/StateMap/Parsing/StateMapParser.cpp b/src/ObjLoading/StateMap/Parsing/StateMapParser.cpp index 9e95bc67..ad890a56 100644 --- a/src/ObjLoading/StateMap/Parsing/StateMapParser.cpp +++ b/src/ObjLoading/StateMap/Parsing/StateMapParser.cpp @@ -57,7 +57,8 @@ namespace state_map class SequenceCondition final : public StateMapParser::sequence_t { - StateMapExpressionMatchers m_expression_matchers; + static constexpr auto TAG_DEFAULT = 1; + static constexpr auto TAG_EXPRESSION = 2; public: SequenceCondition() @@ -66,7 +67,10 @@ namespace state_map const SimpleMatcherFactory create(this); AddMatchers({ - create.Label(StateMapExpressionMatchers::LABEL_EXPRESSION), + create.Or({ + create.Keyword("default").Tag(TAG_DEFAULT), + create.Label(StateMapExpressionMatchers::LABEL_EXPRESSION).Tag(TAG_EXPRESSION) + }), create.Char(':') }); } @@ -74,10 +78,9 @@ namespace state_map protected: void ProcessMatch(StateMapParserState* state, SequenceResult& result) const override { + assert(state->m_definition); assert(state->m_in_entry); - auto expression = m_expression_matchers.ProcessExpression(result); - if (!state->m_current_rule) { auto newRule = std::make_unique(); @@ -85,8 +88,23 @@ namespace state_map state->m_definition->m_state_map_entries[state->m_current_entry_index].m_rules.emplace_back(std::move(newRule)); } - state->m_current_rule->m_conditions.emplace_back(std::move(expression)); + if (result.PeekAndRemoveIfTag(TAG_EXPRESSION) == TAG_EXPRESSION) + { + auto expression = m_expression_matchers.ProcessExpression(result); + + state->m_current_rule->m_conditions.emplace_back(std::move(expression)); + } + else + { + assert(result.PeekAndRemoveIfTag(TAG_DEFAULT) == TAG_DEFAULT); + auto& entry = state->m_definition->m_state_map_entries[state->m_current_entry_index]; + entry.m_has_default = true; + entry.m_default_index = entry.m_rules.size() - 1; + } } + + private: + StateMapExpressionMatchers m_expression_matchers; }; class SequenceValue final : public StateMapParser::sequence_t diff --git a/src/ObjLoading/StateMap/StateMapDefinition.cpp b/src/ObjLoading/StateMap/StateMapDefinition.cpp index 3f23db1b..e8b64045 100644 --- a/src/ObjLoading/StateMap/StateMapDefinition.cpp +++ b/src/ObjLoading/StateMap/StateMapDefinition.cpp @@ -7,6 +7,12 @@ bool StateMapRule::IsPassthrough() const return m_values.empty(); } +StateMapEntry::StateMapEntry() + : m_has_default(false), + m_default_index(0u) +{ +} + StateMapDefinition::StateMapDefinition(std::string name, const size_t entryCount) : m_name(std::move(name)), m_state_map_entries(entryCount) diff --git a/src/ObjLoading/StateMap/StateMapDefinition.h b/src/ObjLoading/StateMap/StateMapDefinition.h index 9b10148f..173ef994 100644 --- a/src/ObjLoading/StateMap/StateMapDefinition.h +++ b/src/ObjLoading/StateMap/StateMapDefinition.h @@ -14,14 +14,18 @@ namespace state_map public: std::vector> m_conditions; std::vector m_values; - + _NODISCARD bool IsPassthrough() const; }; class StateMapEntry { public: + bool m_has_default; + size_t m_default_index; std::vector> m_rules; + + StateMapEntry(); }; class StateMapDefinition