mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
implement count sequence parsing
This commit is contained in:
parent
4a0395c5df
commit
3ffcac04dd
@ -103,9 +103,9 @@ static constexpr int TAG_EVALUATION = std::numeric_limits<int>::max() - 9;
|
||||
static constexpr int TAG_EVALUATION_OPERATION = std::numeric_limits<int>::max() - 10;
|
||||
|
||||
static constexpr int CAPTURE_OPERAND_TYPENAME = std::numeric_limits<int>::max() - 1;
|
||||
static constexpr int CAPTURE_OPERAND_ARRAY = std::numeric_limits<int>::max() - 1;
|
||||
static constexpr int CAPTURE_OPERAND_INTEGER = std::numeric_limits<int>::max() - 2;
|
||||
static constexpr int CAPTURE_OPERATION_TYPE = std::numeric_limits<int>::max() - 3;
|
||||
static constexpr int CAPTURE_OPERAND_ARRAY = std::numeric_limits<int>::max() - 2;
|
||||
static constexpr int CAPTURE_OPERAND_INTEGER = std::numeric_limits<int>::max() - 3;
|
||||
static constexpr int CAPTURE_OPERATION_TYPE = std::numeric_limits<int>::max() - 4;
|
||||
|
||||
std::unique_ptr<CommandsCommonMatchers::matcher_t> CommandsCommonMatchers::ParseOperandArray(const supplier_t* labelSupplier)
|
||||
{
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "SequenceCount.h"
|
||||
|
||||
#include "Domain/Definition/ArrayDeclarationModifier.h"
|
||||
#include "Domain/Definition/PointerDeclarationModifier.h"
|
||||
#include "Parsing/Commands/Matcher/CommandsMatcherFactory.h"
|
||||
#include "Parsing/Commands/Matcher/CommandsCommonMatchers.h"
|
||||
|
||||
@ -11,16 +13,116 @@ SequenceCount::SequenceCount()
|
||||
AddLabeledMatchers(CommandsCommonMatchers::Evaluation(this), CommandsCommonMatchers::LABEL_EVALUATION);
|
||||
AddLabeledMatchers(CommandsCommonMatchers::ArrayDef(this), CommandsCommonMatchers::LABEL_ARRAY_DEF);
|
||||
AddMatchers({
|
||||
create.Keyword("set"),
|
||||
create.Keyword("set").Capture(CAPTURE_START),
|
||||
create.Keyword("count"),
|
||||
create.OptionalLoop(create.Char('*').Tag(TAG_POINTER_RESOLVE)),
|
||||
create.Label(CommandsCommonMatchers::LABEL_TYPENAME).Capture(CAPTURE_TYPE),
|
||||
create.OptionalLoop(create.Label(CommandsCommonMatchers::LABEL_ARRAY_DEF).Capture(CAPTURE_ARRAY_INDEX)),
|
||||
create.Label(CommandsCommonMatchers::LABEL_EVALUATION).Capture(CAPTURE_EVALUATION),
|
||||
create.Label(CommandsCommonMatchers::LABEL_EVALUATION),
|
||||
create.Char(';')
|
||||
});
|
||||
}
|
||||
|
||||
void SequenceCount::SetCountByArrayIndex(CommandsParserState* state, SequenceResult<CommandsParserValue>& result, MemberInformation* member, PointerDeclarationModifier* pointer,
|
||||
std::unique_ptr<IEvaluation> evaluation)
|
||||
{
|
||||
std::vector<int> arraySizes;
|
||||
std::vector<int> depthSize;
|
||||
for (const auto& modifier : member->m_member->m_type_declaration->m_declaration_modifiers)
|
||||
{
|
||||
if (modifier->GetType() == DeclarationModifierType::ARRAY)
|
||||
arraySizes.push_back(dynamic_cast<ArrayDeclarationModifier*>(modifier.get())->m_size);
|
||||
}
|
||||
|
||||
depthSize.resize(arraySizes.size());
|
||||
auto currentDepthSize = 1u;
|
||||
for (auto i = arraySizes.size(); i > 0; i--)
|
||||
{
|
||||
if(i < arraySizes.size())
|
||||
currentDepthSize *= arraySizes[i];
|
||||
depthSize[i - 1] = currentDepthSize;
|
||||
}
|
||||
|
||||
if (pointer->m_count_evaluation_by_array_index.empty())
|
||||
{
|
||||
auto neededCapacity = 0u;
|
||||
for (auto arraySize : arraySizes)
|
||||
{
|
||||
if (neededCapacity == 0)
|
||||
neededCapacity = arraySize;
|
||||
else
|
||||
neededCapacity *= arraySize;
|
||||
}
|
||||
pointer->m_count_evaluation_by_array_index.resize(neededCapacity);
|
||||
}
|
||||
|
||||
auto currentIndex = 0u;
|
||||
auto currentIndexOffset = 0u;
|
||||
while (result.HasNextCapture(CAPTURE_ARRAY_INDEX) && currentIndexOffset < depthSize.size())
|
||||
{
|
||||
const auto& arrayIndexToken = result.NextCapture(CAPTURE_ARRAY_INDEX);
|
||||
if (arrayIndexToken.m_type == CommandsParserValueType::INTEGER)
|
||||
{
|
||||
currentIndex += depthSize[currentIndexOffset++] * arrayIndexToken.IntegerValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto* enumEntry = state->GetRepository()->GetEnumMemberByName(arrayIndexToken.IdentifierValue());
|
||||
if (enumEntry == nullptr)
|
||||
throw ParsingException(arrayIndexToken.GetPos(), "Unknown enum entry");
|
||||
|
||||
currentIndex += depthSize[currentIndexOffset++] * enumEntry->m_value;
|
||||
}
|
||||
}
|
||||
|
||||
pointer->m_count_evaluation_by_array_index[currentIndex] = std::move(evaluation);
|
||||
}
|
||||
|
||||
void SequenceCount::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
|
||||
{
|
||||
const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE);
|
||||
|
||||
StructureInformation* type;
|
||||
std::vector<MemberInformation*> memberChain;
|
||||
if (!state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), type, memberChain))
|
||||
throw ParsingException(typeNameToken.GetPos(), "Unknown type");
|
||||
|
||||
if (memberChain.empty())
|
||||
throw ParsingException(typeNameToken.GetPos(), "Conditions can only be set on members and not for types");
|
||||
|
||||
auto resolve = 0u;
|
||||
while (result.PeekAndRemoveIfTag(TAG_POINTER_RESOLVE) == TAG_POINTER_RESOLVE)
|
||||
resolve++;
|
||||
|
||||
auto* lastMember = memberChain.back();
|
||||
PointerDeclarationModifier* pointer = nullptr;
|
||||
for (const auto& modifier : lastMember->m_member->m_type_declaration->m_declaration_modifiers)
|
||||
{
|
||||
if (modifier->GetType() == DeclarationModifierType::POINTER)
|
||||
{
|
||||
if (resolve > 0)
|
||||
{
|
||||
resolve--;
|
||||
}
|
||||
else
|
||||
{
|
||||
pointer = dynamic_cast<PointerDeclarationModifier*>(modifier.get());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pointer == nullptr)
|
||||
throw ParsingException(result.NextCapture(CAPTURE_START).GetPos(), "No matching pointer modifier found");
|
||||
|
||||
auto countEvaluation = CommandsCommonMatchers::ProcessEvaluation(state, result, type);
|
||||
|
||||
if (!result.HasNextCapture(CAPTURE_ARRAY_INDEX))
|
||||
{
|
||||
pointer->m_count_evaluation = std::move(countEvaluation);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCountByArrayIndex(state, result, lastMember, pointer, std::move(countEvaluation));
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "Domain/Definition/PointerDeclarationModifier.h"
|
||||
#include "Parsing/Commands/Impl/CommandsParser.h"
|
||||
|
||||
class SequenceCount final : public CommandsParser::sequence_t
|
||||
{
|
||||
static constexpr auto TAG_POINTER_RESOLVE = 1;
|
||||
|
||||
static constexpr auto CAPTURE_TYPE = 1;
|
||||
static constexpr auto CAPTURE_ARRAY_INDEX = 2;
|
||||
static constexpr auto CAPTURE_EVALUATION = 3;
|
||||
static constexpr auto CAPTURE_START = 1;
|
||||
static constexpr auto CAPTURE_TYPE = 2;
|
||||
static constexpr auto CAPTURE_ARRAY_INDEX = 3;
|
||||
|
||||
static void SetCountByArrayIndex(CommandsParserState* state, SequenceResult<CommandsParserValue>& result, MemberInformation* member, PointerDeclarationModifier* pointer,
|
||||
std::unique_ptr<IEvaluation> evaluation);
|
||||
|
||||
protected:
|
||||
void ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const override;
|
||||
|
Loading…
x
Reference in New Issue
Block a user