Correctly parse state map default case

This commit is contained in:
Jan 2022-08-13 21:13:07 +02:00
parent 16218e2bce
commit b93707dfe5
3 changed files with 34 additions and 6 deletions

View File

@ -57,7 +57,8 @@ namespace state_map
class SequenceCondition final : public StateMapParser::sequence_t class SequenceCondition final : public StateMapParser::sequence_t
{ {
StateMapExpressionMatchers m_expression_matchers; static constexpr auto TAG_DEFAULT = 1;
static constexpr auto TAG_EXPRESSION = 2;
public: public:
SequenceCondition() SequenceCondition()
@ -66,7 +67,10 @@ namespace state_map
const SimpleMatcherFactory create(this); const SimpleMatcherFactory create(this);
AddMatchers({ AddMatchers({
create.Label(StateMapExpressionMatchers::LABEL_EXPRESSION), create.Or({
create.Keyword("default").Tag(TAG_DEFAULT),
create.Label(StateMapExpressionMatchers::LABEL_EXPRESSION).Tag(TAG_EXPRESSION)
}),
create.Char(':') create.Char(':')
}); });
} }
@ -74,10 +78,9 @@ namespace state_map
protected: protected:
void ProcessMatch(StateMapParserState* state, SequenceResult<SimpleParserValue>& result) const override void ProcessMatch(StateMapParserState* state, SequenceResult<SimpleParserValue>& result) const override
{ {
assert(state->m_definition);
assert(state->m_in_entry); assert(state->m_in_entry);
auto expression = m_expression_matchers.ProcessExpression(result);
if (!state->m_current_rule) if (!state->m_current_rule)
{ {
auto newRule = std::make_unique<StateMapRule>(); auto newRule = std::make_unique<StateMapRule>();
@ -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_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 class SequenceValue final : public StateMapParser::sequence_t

View File

@ -7,6 +7,12 @@ bool StateMapRule::IsPassthrough() const
return m_values.empty(); return m_values.empty();
} }
StateMapEntry::StateMapEntry()
: m_has_default(false),
m_default_index(0u)
{
}
StateMapDefinition::StateMapDefinition(std::string name, const size_t entryCount) StateMapDefinition::StateMapDefinition(std::string name, const size_t entryCount)
: m_name(std::move(name)), : m_name(std::move(name)),
m_state_map_entries(entryCount) m_state_map_entries(entryCount)

View File

@ -21,7 +21,11 @@ namespace state_map
class StateMapEntry class StateMapEntry
{ {
public: public:
bool m_has_default;
size_t m_default_index;
std::vector<std::unique_ptr<StateMapRule>> m_rules; std::vector<std::unique_ptr<StateMapRule>> m_rules;
StateMapEntry();
}; };
class StateMapDefinition class StateMapDefinition