mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-10 14:58:10 -05:00
Move StructuredDataDef Parsing to new package
This commit is contained in:
@ -1,157 +0,0 @@
|
||||
#include "StructuredDataDefScopeSequences.h"
|
||||
|
||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||
|
||||
namespace sdd::def_scope_sequences
|
||||
{
|
||||
class SequenceEnum final : public StructuredDataDefParser::sequence_t
|
||||
{
|
||||
static constexpr auto CAPTURE_NAME = 1;
|
||||
static constexpr auto CAPTURE_RESERVED_COUNT = 2;
|
||||
|
||||
public:
|
||||
SequenceEnum()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Keyword("enum"),
|
||||
create.Optional(create.And({
|
||||
create.Char('('),
|
||||
create.Integer().Capture(CAPTURE_RESERVED_COUNT),
|
||||
create.Char(')')
|
||||
})),
|
||||
create.Identifier().Capture(CAPTURE_NAME),
|
||||
create.Char('{')
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
assert(state->m_current_def);
|
||||
|
||||
auto newEnum = std::make_unique<CommonStructuredDataEnum>(result.NextCapture(CAPTURE_NAME).IdentifierValue());
|
||||
if (result.HasNextCapture(CAPTURE_RESERVED_COUNT))
|
||||
{
|
||||
const auto& reservedCountToken = result.NextCapture(CAPTURE_RESERVED_COUNT);
|
||||
newEnum->m_reserved_entry_count = reservedCountToken.IntegerValue();
|
||||
|
||||
if (newEnum->m_reserved_entry_count <= 0)
|
||||
throw ParsingException(reservedCountToken.GetPos(), "Reserved enum entry count must be greater than zero");
|
||||
}
|
||||
|
||||
state->m_current_enum = newEnum.get();
|
||||
state->m_def_types_by_name.emplace(newEnum->m_name, CommonStructuredDataType(CommonStructuredDataTypeCategory::ENUM, state->m_current_def->m_enums.size()));
|
||||
state->m_current_def->m_enums.emplace_back(std::move(newEnum));
|
||||
}
|
||||
};
|
||||
|
||||
class SequenceStruct final : public StructuredDataDefParser::sequence_t
|
||||
{
|
||||
static constexpr auto CAPTURE_NAME = 1;
|
||||
|
||||
public:
|
||||
SequenceStruct()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Keyword("struct"),
|
||||
create.Identifier().Capture(CAPTURE_NAME),
|
||||
create.Char('{')
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
assert(state->m_current_def);
|
||||
|
||||
auto newStruct = std::make_unique<CommonStructuredDataStruct>(result.NextCapture(CAPTURE_NAME).IdentifierValue());
|
||||
auto* newStructPtr = newStruct.get();
|
||||
const auto newStructIndex = state->m_current_def->m_structs.size();
|
||||
|
||||
state->m_current_struct = newStructPtr;
|
||||
state->m_def_types_by_name.emplace(newStruct->m_name, CommonStructuredDataType(CommonStructuredDataTypeCategory::STRUCT, newStructIndex));
|
||||
state->m_current_def->m_structs.emplace_back(std::move(newStruct));
|
||||
state->m_current_struct_offset_in_bits = 0;
|
||||
|
||||
if (newStructPtr->m_name == "root")
|
||||
{
|
||||
state->m_current_struct_offset_in_bits = 64u;
|
||||
state->m_current_def->m_root_type = CommonStructuredDataType(CommonStructuredDataTypeCategory::STRUCT, newStructIndex);
|
||||
}
|
||||
else
|
||||
state->m_current_struct_offset_in_bits = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class SequenceCloseScope final : public StructuredDataDefParser::sequence_t
|
||||
{
|
||||
static constexpr auto CAPTURE_NAME = 1;
|
||||
|
||||
public:
|
||||
SequenceCloseScope()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Char('}')
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
static void CreateDefaultStructWhenNoStructsSpecified(const StructuredDataDefParserState* state)
|
||||
{
|
||||
if (state->m_current_def->m_structs.empty())
|
||||
{
|
||||
state->m_current_def->m_structs.emplace_back(std::make_unique<CommonStructuredDataStruct>());
|
||||
state->m_current_def->m_root_type = CommonStructuredDataType(CommonStructuredDataTypeCategory::STRUCT, 0u);
|
||||
}
|
||||
}
|
||||
|
||||
static void SetDefSizeFromRootStruct(const StructuredDataDefParserState* state)
|
||||
{
|
||||
if (state->m_current_def->m_root_type.m_category == CommonStructuredDataTypeCategory::STRUCT
|
||||
&& state->m_current_def->m_root_type.m_info.type_index < state->m_current_def->m_structs.size())
|
||||
{
|
||||
const auto* _struct = state->m_current_def->m_structs[state->m_current_def->m_root_type.m_info.type_index].get();
|
||||
state->m_current_def->m_size_in_byte = _struct->m_size_in_byte;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
assert(state->m_current_enum == nullptr);
|
||||
assert(state->m_current_struct == nullptr);
|
||||
|
||||
CreateDefaultStructWhenNoStructsSpecified(state);
|
||||
SetDefSizeFromRootStruct(state);
|
||||
|
||||
// TODO: Calculate checksum here
|
||||
|
||||
state->m_current_def = nullptr;
|
||||
state->m_def_types_by_name.clear();
|
||||
state->m_def_indexed_arrays.clear();
|
||||
state->m_def_enumed_arrays.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
using namespace sdd;
|
||||
using namespace def_scope_sequences;
|
||||
|
||||
StructuredDataDefScopeSequences::StructuredDataDefScopeSequences(std::vector<std::unique_ptr<StructuredDataDefParser::sequence_t>>& allSequences,
|
||||
std::vector<StructuredDataDefParser::sequence_t*>& scopeSequences)
|
||||
: AbstractScopeSequenceHolder(allSequences, scopeSequences)
|
||||
{
|
||||
}
|
||||
|
||||
void StructuredDataDefScopeSequences::AddSequences() const
|
||||
{
|
||||
AddSequence(std::make_unique<SequenceCloseScope>());
|
||||
AddSequence(std::make_unique<SequenceEnum>());
|
||||
AddSequence(std::make_unique<SequenceStruct>());
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Sequence/AbstractScopeSequenceHolder.h"
|
||||
#include "Parsing/StructuredDataDef/StructuredDataDefParser.h"
|
||||
|
||||
namespace sdd
|
||||
{
|
||||
class StructuredDataDefScopeSequences final : AbstractScopeSequenceHolder<StructuredDataDefParser>
|
||||
{
|
||||
public:
|
||||
StructuredDataDefScopeSequences(std::vector<std::unique_ptr<StructuredDataDefParser::sequence_t>>& allSequences, std::vector<StructuredDataDefParser::sequence_t*>& scopeSequences);
|
||||
|
||||
void AddSequences() const;
|
||||
};
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
#include "StructuredDataEnumScopeSequences.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||
|
||||
namespace sdd::enum_scope_sequences
|
||||
{
|
||||
class SequenceEnumEntry final : public StructuredDataDefParser::sequence_t
|
||||
{
|
||||
static constexpr auto CAPTURE_ENTRY_VALUE = 1;
|
||||
|
||||
public:
|
||||
SequenceEnumEntry()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.String().Capture(CAPTURE_ENTRY_VALUE),
|
||||
create.Or({
|
||||
create.Char(','),
|
||||
create.Char('}').NoConsume()
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
assert(state->m_current_enum);
|
||||
|
||||
const auto& entryValueToken = result.NextCapture(CAPTURE_ENTRY_VALUE);
|
||||
if (state->m_current_enum->m_reserved_entry_count > 0 && static_cast<size_t>(state->m_current_enum->m_reserved_entry_count) <= state->m_current_enum->m_entries.size())
|
||||
throw ParsingException(entryValueToken.GetPos(), "Enum entry count exceeds reserved count");
|
||||
|
||||
state->m_current_enum->m_entries.emplace_back(entryValueToken.StringValue(), state->m_current_enum->m_entries.size());
|
||||
}
|
||||
};
|
||||
|
||||
class SequenceCloseEnum final : public StructuredDataDefParser::sequence_t
|
||||
{
|
||||
public:
|
||||
SequenceCloseEnum()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Char('}'),
|
||||
create.Optional(create.Char(';'))
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
assert(state->m_current_enum != nullptr);
|
||||
|
||||
std::sort(state->m_current_enum->m_entries.begin(), state->m_current_enum->m_entries.end(), [](const CommonStructuredDataEnumEntry& e1, const CommonStructuredDataEnumEntry& e2)
|
||||
{
|
||||
return e1.m_name < e2.m_name;
|
||||
});
|
||||
|
||||
state->m_current_enum = nullptr;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
using namespace sdd;
|
||||
using namespace enum_scope_sequences;
|
||||
|
||||
StructuredDataEnumScopeSequences::StructuredDataEnumScopeSequences(std::vector<std::unique_ptr<StructuredDataDefParser::sequence_t>>& allSequences,
|
||||
std::vector<StructuredDataDefParser::sequence_t*>& scopeSequences)
|
||||
: AbstractScopeSequenceHolder(allSequences, scopeSequences)
|
||||
{
|
||||
}
|
||||
|
||||
void StructuredDataEnumScopeSequences::AddSequences() const
|
||||
{
|
||||
AddSequence(std::make_unique<SequenceCloseEnum>());
|
||||
AddSequence(std::make_unique<SequenceEnumEntry>());
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Sequence/AbstractScopeSequenceHolder.h"
|
||||
#include "Parsing/StructuredDataDef/StructuredDataDefParser.h"
|
||||
|
||||
namespace sdd
|
||||
{
|
||||
class StructuredDataEnumScopeSequences final : AbstractScopeSequenceHolder<StructuredDataDefParser>
|
||||
{
|
||||
public:
|
||||
StructuredDataEnumScopeSequences(std::vector<std::unique_ptr<StructuredDataDefParser::sequence_t>>& allSequences, std::vector<StructuredDataDefParser::sequence_t*>& scopeSequences);
|
||||
|
||||
void AddSequences() const;
|
||||
};
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
#include "StructuredDataNoScopeSequences.h"
|
||||
|
||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||
|
||||
namespace sdd::no_scope_sequences
|
||||
{
|
||||
class SequenceVersion final : public StructuredDataDefParser::sequence_t
|
||||
{
|
||||
static constexpr auto CAPTURE_VERSION = 1;
|
||||
|
||||
public:
|
||||
SequenceVersion()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Keyword("version"),
|
||||
create.Integer().Capture(CAPTURE_VERSION),
|
||||
create.Char('{')
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
auto newDef = std::make_unique<CommonStructuredDataDef>(result.NextCapture(CAPTURE_VERSION).IntegerValue());
|
||||
state->m_current_def = newDef.get();
|
||||
state->m_defs.emplace_back(std::move(newDef));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
using namespace sdd;
|
||||
using namespace no_scope_sequences;
|
||||
|
||||
StructuredDataNoScopeSequences::StructuredDataNoScopeSequences(std::vector<std::unique_ptr<StructuredDataDefParser::sequence_t>>& allSequences,
|
||||
std::vector<StructuredDataDefParser::sequence_t*>& scopeSequences)
|
||||
: AbstractScopeSequenceHolder(allSequences, scopeSequences)
|
||||
{
|
||||
}
|
||||
|
||||
void StructuredDataNoScopeSequences::AddSequences() const
|
||||
{
|
||||
AddSequence(std::make_unique<SequenceVersion>());
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Sequence/AbstractScopeSequenceHolder.h"
|
||||
#include "Parsing/StructuredDataDef/StructuredDataDefParser.h"
|
||||
|
||||
namespace sdd
|
||||
{
|
||||
class StructuredDataNoScopeSequences final : AbstractScopeSequenceHolder<StructuredDataDefParser>
|
||||
{
|
||||
public:
|
||||
StructuredDataNoScopeSequences(std::vector<std::unique_ptr<StructuredDataDefParser::sequence_t>>& allSequences, std::vector<StructuredDataDefParser::sequence_t*>& scopeSequences);
|
||||
|
||||
void AddSequences() const;
|
||||
};
|
||||
}
|
@ -1,307 +0,0 @@
|
||||
#include "StructuredDataStructScopeSequences.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||
|
||||
namespace sdd::struct_scope_sequences
|
||||
{
|
||||
class SequenceStructEntry final : public StructuredDataDefParser::sequence_t
|
||||
{
|
||||
static constexpr auto TAG_TYPE_INT = 1;
|
||||
static constexpr auto TAG_TYPE_BYTE = 2;
|
||||
static constexpr auto TAG_TYPE_BOOL = 3;
|
||||
static constexpr auto TAG_TYPE_FLOAT = 4;
|
||||
static constexpr auto TAG_TYPE_SHORT = 5;
|
||||
static constexpr auto TAG_TYPE_STRING = 6;
|
||||
static constexpr auto TAG_TYPE_NAMED = 7;
|
||||
|
||||
static constexpr auto CAPTURE_STRING_LENGTH = 1;
|
||||
static constexpr auto CAPTURE_TYPE_NAME = 2;
|
||||
static constexpr auto CAPTURE_ENTRY_NAME = 3;
|
||||
static constexpr auto CAPTURE_ARRAY_SIZE = 4;
|
||||
|
||||
static std::unique_ptr<matcher_t> TypeMatchers(const SimpleMatcherFactory& create)
|
||||
{
|
||||
return create.Or({
|
||||
create.Keyword("int").Tag(TAG_TYPE_INT),
|
||||
create.Keyword("byte").Tag(TAG_TYPE_BYTE),
|
||||
create.Keyword("bool").Tag(TAG_TYPE_BOOL),
|
||||
create.Keyword("float").Tag(TAG_TYPE_FLOAT),
|
||||
create.Keyword("short").Tag(TAG_TYPE_SHORT),
|
||||
create.And({
|
||||
create.Keyword("string"),
|
||||
create.Char('('),
|
||||
create.Integer().Capture(CAPTURE_STRING_LENGTH),
|
||||
create.Char(')')
|
||||
}).Tag(TAG_TYPE_STRING),
|
||||
create.Identifier().Tag(TAG_TYPE_NAMED).Capture(CAPTURE_TYPE_NAME)
|
||||
});
|
||||
}
|
||||
|
||||
static std::unique_ptr<matcher_t> ArrayMatchers(const SimpleMatcherFactory& create)
|
||||
{
|
||||
return create.And({
|
||||
create.Char('['),
|
||||
create.Or({
|
||||
create.Integer().Capture(CAPTURE_ARRAY_SIZE),
|
||||
create.Identifier().Capture(CAPTURE_ARRAY_SIZE)
|
||||
}),
|
||||
create.Char(']')
|
||||
});
|
||||
}
|
||||
|
||||
public:
|
||||
SequenceStructEntry()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
TypeMatchers(create),
|
||||
create.Identifier().Capture(CAPTURE_ENTRY_NAME),
|
||||
create.OptionalLoop(ArrayMatchers(create)),
|
||||
create.Char(';')
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
static CommonStructuredDataType ProcessType(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result, size_t& currentSize, size_t& currentBitAlign)
|
||||
{
|
||||
const auto typeTag = result.NextTag();
|
||||
|
||||
switch (typeTag)
|
||||
{
|
||||
case TAG_TYPE_INT:
|
||||
currentSize = 32;
|
||||
currentBitAlign = 8;
|
||||
return CommonStructuredDataType(CommonStructuredDataTypeCategory::INT);
|
||||
case TAG_TYPE_BYTE:
|
||||
currentSize = 8;
|
||||
currentBitAlign = 8;
|
||||
return CommonStructuredDataType(CommonStructuredDataTypeCategory::BYTE);
|
||||
case TAG_TYPE_BOOL:
|
||||
currentSize = 1;
|
||||
currentBitAlign = 0;
|
||||
return CommonStructuredDataType(CommonStructuredDataTypeCategory::BOOL);
|
||||
case TAG_TYPE_FLOAT:
|
||||
currentSize = 32;
|
||||
currentBitAlign = 8;
|
||||
return CommonStructuredDataType(CommonStructuredDataTypeCategory::FLOAT);
|
||||
case TAG_TYPE_SHORT:
|
||||
currentSize = 16;
|
||||
currentBitAlign = 8;
|
||||
return CommonStructuredDataType(CommonStructuredDataTypeCategory::SHORT);
|
||||
case TAG_TYPE_STRING:
|
||||
{
|
||||
currentBitAlign = 8;
|
||||
const auto& stringLengthToken = result.NextCapture(CAPTURE_STRING_LENGTH);
|
||||
const auto stringLength = stringLengthToken.IntegerValue();
|
||||
|
||||
if (stringLength <= 0)
|
||||
throw ParsingException(stringLengthToken.GetPos(), "String length must be greater than zero");
|
||||
|
||||
currentSize = stringLength * 8;
|
||||
return {CommonStructuredDataTypeCategory::STRING, static_cast<size_t>(stringLength)};
|
||||
}
|
||||
case TAG_TYPE_NAMED:
|
||||
{
|
||||
currentBitAlign = 8;
|
||||
const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE_NAME);
|
||||
const auto typeName = typeNameToken.IdentifierValue();
|
||||
|
||||
const auto existingType = state->m_def_types_by_name.find(typeName);
|
||||
if (existingType == state->m_def_types_by_name.end())
|
||||
throw ParsingException(typeNameToken.GetPos(), "No type defined under this name");
|
||||
|
||||
if (existingType->second.m_category == CommonStructuredDataTypeCategory::STRUCT)
|
||||
{
|
||||
assert(existingType->second.m_info.type_index < state->m_current_def->m_structs.size());
|
||||
const auto* _struct = state->m_current_def->m_structs[existingType->second.m_info.type_index].get();
|
||||
currentSize = _struct->m_size_in_byte * 8;
|
||||
}
|
||||
else if (existingType->second.m_category == CommonStructuredDataTypeCategory::ENUM)
|
||||
{
|
||||
assert(existingType->second.m_info.type_index < state->m_current_def->m_enums.size());
|
||||
currentSize = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
currentSize = 0;
|
||||
}
|
||||
|
||||
return existingType->second;
|
||||
}
|
||||
default:
|
||||
throw ParsingException(TokenPos(), "Invalid Tag for Type @ ProcessType!!!");
|
||||
}
|
||||
}
|
||||
|
||||
static CommonStructuredDataType ProcessArray(StructuredDataDefParserState* state, const SimpleParserValue& arrayToken, const CommonStructuredDataType currentType,
|
||||
size_t& currentSize, size_t& currentBitAlign)
|
||||
{
|
||||
currentBitAlign = 8;
|
||||
|
||||
if (arrayToken.m_type == SimpleParserValueType::INTEGER)
|
||||
{
|
||||
const auto arrayElementCount = arrayToken.IntegerValue();
|
||||
|
||||
if (arrayElementCount <= 0)
|
||||
throw ParsingException(arrayToken.GetPos(), "Array size must be greater than zero");
|
||||
|
||||
currentSize *= arrayElementCount;
|
||||
|
||||
const CommonStructuredDataIndexedArray indexedArray(currentType, arrayElementCount);
|
||||
|
||||
const auto existingIndexedArray = state->m_def_indexed_arrays.find(indexedArray);
|
||||
if (existingIndexedArray != state->m_def_indexed_arrays.end())
|
||||
return {CommonStructuredDataTypeCategory::INDEXED_ARRAY, existingIndexedArray->second};
|
||||
|
||||
const auto newIndexedArrayIndex = state->m_current_def->m_indexed_arrays.size();
|
||||
state->m_current_def->m_indexed_arrays.push_back(indexedArray);
|
||||
return {CommonStructuredDataTypeCategory::INDEXED_ARRAY, newIndexedArrayIndex};
|
||||
}
|
||||
|
||||
if (arrayToken.m_type == SimpleParserValueType::IDENTIFIER)
|
||||
{
|
||||
const auto enumName = arrayToken.IdentifierValue();
|
||||
|
||||
const auto existingType = state->m_def_types_by_name.find(enumName);
|
||||
if (existingType == state->m_def_types_by_name.end())
|
||||
throw ParsingException(arrayToken.GetPos(), "No type defined under this name");
|
||||
if (existingType->second.m_category != CommonStructuredDataTypeCategory::ENUM)
|
||||
throw ParsingException(arrayToken.GetPos(), "Type for enumed array must be an enum");
|
||||
|
||||
assert(existingType->second.m_info.type_index < state->m_current_def->m_enums.size());
|
||||
const auto* _enum = state->m_current_def->m_enums[existingType->second.m_info.type_index].get();
|
||||
|
||||
const auto enumElementCount = _enum->ElementCount();
|
||||
assert(enumElementCount > 0);
|
||||
currentSize *= enumElementCount;
|
||||
|
||||
const CommonStructuredDataEnumedArray enumedArray(currentType, existingType->second.m_info.type_index);
|
||||
|
||||
const auto existingEnumedArray = state->m_def_enumed_arrays.find(enumedArray);
|
||||
if (existingEnumedArray != state->m_def_enumed_arrays.end())
|
||||
return {CommonStructuredDataTypeCategory::ENUM_ARRAY, existingEnumedArray->second};
|
||||
|
||||
const auto newEnumedArrayIndex = state->m_current_def->m_enumed_arrays.size();
|
||||
state->m_current_def->m_enumed_arrays.push_back(enumedArray);
|
||||
return {CommonStructuredDataTypeCategory::ENUM_ARRAY, newEnumedArrayIndex};
|
||||
}
|
||||
|
||||
throw ParsingException(arrayToken.GetPos(), "Invalid Token for Array @ ProcessArray!!!");
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
assert(state->m_current_def != nullptr);
|
||||
assert(state->m_current_struct != nullptr);
|
||||
|
||||
size_t currentSize = 0;
|
||||
size_t currentAlign = 0;
|
||||
auto currentType = ProcessType(state, result, currentSize, currentAlign);
|
||||
|
||||
std::vector<std::reference_wrapper<const SimpleParserValue>> arrayTokens;
|
||||
while (result.HasNextCapture(CAPTURE_ARRAY_SIZE))
|
||||
arrayTokens.emplace_back(result.NextCapture(CAPTURE_ARRAY_SIZE));
|
||||
|
||||
for (auto i = arrayTokens.rbegin(); i != arrayTokens.rend(); ++i)
|
||||
currentType = ProcessArray(state, i->get(), currentType, currentSize, currentAlign);
|
||||
|
||||
if (currentAlign > 0)
|
||||
state->m_current_struct_offset_in_bits = (state->m_current_struct_offset_in_bits + currentAlign - 1) / currentAlign * currentAlign;
|
||||
|
||||
state->m_current_struct->m_properties.emplace_back(result.NextCapture(CAPTURE_ENTRY_NAME).IdentifierValue(), currentType, state->m_current_struct_offset_in_bits);
|
||||
state->m_current_struct_offset_in_bits += currentSize;
|
||||
}
|
||||
};
|
||||
|
||||
class SequencePadding final : public StructuredDataDefParser::sequence_t
|
||||
{
|
||||
static constexpr auto CAPTURE_PADDING_VALUE = 1;
|
||||
|
||||
public:
|
||||
SequencePadding()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Keyword("pad"),
|
||||
create.Char('('),
|
||||
create.Integer().Capture(CAPTURE_PADDING_VALUE),
|
||||
create.Char(')'),
|
||||
create.Char(';')
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
const auto& paddingValueToken = result.NextCapture(CAPTURE_PADDING_VALUE);
|
||||
const auto paddingValue = paddingValueToken.IntegerValue();
|
||||
|
||||
if (paddingValue <= 0)
|
||||
throw ParsingException(paddingValueToken.GetPos(), "Padding value must be greater than 0");
|
||||
|
||||
// Align to next byte
|
||||
state->m_current_struct_offset_in_bits = (state->m_current_struct_offset_in_bits + 7) / 8 * 8;
|
||||
|
||||
// Add padding value to current size
|
||||
state->m_current_struct_offset_in_bits += static_cast<size_t>(paddingValue);
|
||||
}
|
||||
};
|
||||
|
||||
class SequenceCloseStruct final : public StructuredDataDefParser::sequence_t
|
||||
{
|
||||
public:
|
||||
SequenceCloseStruct()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Char('}'),
|
||||
create.Optional(create.Char(';'))
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
assert(state->m_current_struct != nullptr);
|
||||
|
||||
// Set the size of the finalized struct
|
||||
if (!state->m_current_struct->m_properties.empty())
|
||||
state->m_current_struct->m_size_in_byte = (state->m_current_struct_offset_in_bits + 7) / 8;
|
||||
else
|
||||
state->m_current_struct->m_size_in_byte = 0u;
|
||||
|
||||
state->m_current_struct_offset_in_bits = 0u;
|
||||
|
||||
// Sort the entries of the struct alphabetically
|
||||
std::sort(state->m_current_struct->m_properties.begin(), state->m_current_struct->m_properties.end(),
|
||||
[](const CommonStructuredDataStructProperty& e1, const CommonStructuredDataStructProperty& e2)
|
||||
{
|
||||
return e1.m_name < e2.m_name;
|
||||
});
|
||||
state->m_current_struct = nullptr;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
using namespace sdd;
|
||||
using namespace struct_scope_sequences;
|
||||
|
||||
StructuredDataStructScopeSequences::StructuredDataStructScopeSequences(std::vector<std::unique_ptr<StructuredDataDefParser::sequence_t>>& allSequences,
|
||||
std::vector<StructuredDataDefParser::sequence_t*>& scopeSequences)
|
||||
: AbstractScopeSequenceHolder(allSequences, scopeSequences)
|
||||
{
|
||||
}
|
||||
|
||||
void StructuredDataStructScopeSequences::AddSequences() const
|
||||
{
|
||||
AddSequence(std::make_unique<SequenceCloseStruct>());
|
||||
AddSequence(std::make_unique<SequencePadding>());
|
||||
AddSequence(std::make_unique<SequenceStructEntry>());
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Sequence/AbstractScopeSequenceHolder.h"
|
||||
#include "Parsing/StructuredDataDef/StructuredDataDefParser.h"
|
||||
|
||||
namespace sdd
|
||||
{
|
||||
class StructuredDataStructScopeSequences final : AbstractScopeSequenceHolder<StructuredDataDefParser>
|
||||
{
|
||||
public:
|
||||
StructuredDataStructScopeSequences(std::vector<std::unique_ptr<StructuredDataDefParser::sequence_t>>& allSequences, std::vector<StructuredDataDefParser::sequence_t*>& scopeSequences);
|
||||
|
||||
void AddSequences() const;
|
||||
};
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
#include "StructuredDataDefParser.h"
|
||||
|
||||
#include "Sequence/StructuredDataDefScopeSequences.h"
|
||||
#include "Sequence/StructuredDataEnumScopeSequences.h"
|
||||
#include "Sequence/StructuredDataNoScopeSequences.h"
|
||||
#include "Sequence/StructuredDataStructScopeSequences.h"
|
||||
|
||||
using namespace sdd;
|
||||
|
||||
StructuredDataDefParser::StructuredDataDefParser(SimpleLexer* lexer)
|
||||
: AbstractParser(lexer, std::make_unique<StructuredDataDefParserState>())
|
||||
{
|
||||
CreateSequenceCollections();
|
||||
}
|
||||
|
||||
void StructuredDataDefParser::CreateSequenceCollections()
|
||||
{
|
||||
m_all_tests.clear();
|
||||
m_no_scope_tests.clear();
|
||||
m_def_tests.clear();
|
||||
m_enum_tests.clear();
|
||||
m_struct_tests.clear();
|
||||
|
||||
const StructuredDataNoScopeSequences noScopeSequences(m_all_tests, m_no_scope_tests);
|
||||
noScopeSequences.AddSequences();
|
||||
|
||||
const StructuredDataDefScopeSequences defScopeSequences(m_all_tests, m_def_tests);
|
||||
defScopeSequences.AddSequences();
|
||||
|
||||
const StructuredDataEnumScopeSequences enumScopeSequences(m_all_tests, m_enum_tests);
|
||||
enumScopeSequences.AddSequences();
|
||||
|
||||
const StructuredDataStructScopeSequences structScopeSequences(m_all_tests, m_struct_tests);
|
||||
structScopeSequences.AddSequences();
|
||||
}
|
||||
|
||||
const std::vector<StructuredDataDefParser::sequence_t*>& StructuredDataDefParser::GetTestsForState()
|
||||
{
|
||||
if (!m_state->m_current_def)
|
||||
return m_no_scope_tests;
|
||||
|
||||
if (m_state->m_current_enum)
|
||||
return m_enum_tests;
|
||||
|
||||
if (m_state->m_current_struct)
|
||||
return m_struct_tests;
|
||||
|
||||
return m_def_tests;
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<CommonStructuredDataDef>> StructuredDataDefParser::GetDefs() const
|
||||
{
|
||||
return std::move(m_state->m_defs);
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "StructuredDataDefParserState.h"
|
||||
#include "StructuredDataDef/CommonStructuredDataDef.h"
|
||||
#include "Parsing/Simple/SimpleLexer.h"
|
||||
#include "Parsing/Simple/SimpleParserValue.h"
|
||||
#include "Parsing/Impl/AbstractParser.h"
|
||||
|
||||
namespace sdd
|
||||
{
|
||||
class StructuredDataDefParser final : public AbstractParser<SimpleParserValue, StructuredDataDefParserState>
|
||||
{
|
||||
std::vector<std::unique_ptr<sequence_t>> m_all_tests;
|
||||
std::vector<sequence_t*> m_no_scope_tests;
|
||||
std::vector<sequence_t*> m_def_tests;
|
||||
std::vector<sequence_t*> m_enum_tests;
|
||||
std::vector<sequence_t*> m_struct_tests;
|
||||
|
||||
void CreateSequenceCollections();
|
||||
|
||||
protected:
|
||||
const std::vector<sequence_t*>& GetTestsForState() override;
|
||||
|
||||
public:
|
||||
explicit StructuredDataDefParser(SimpleLexer* lexer);
|
||||
_NODISCARD std::vector<std::unique_ptr<CommonStructuredDataDef>> GetDefs() const;
|
||||
};
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#include "StructuredDataDefParserState.h"
|
||||
|
||||
using namespace sdd;
|
||||
|
||||
StructuredDataDefParserState::StructuredDataDefParserState()
|
||||
: m_current_def(nullptr),
|
||||
m_current_enum(nullptr),
|
||||
m_current_struct(nullptr),
|
||||
m_current_struct_offset_in_bits(0u)
|
||||
{
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
#include "StructuredDataDef/CommonStructuredDataDef.h"
|
||||
|
||||
namespace sdd
|
||||
{
|
||||
class StructuredDataDefParserState
|
||||
{
|
||||
public:
|
||||
std::vector<std::unique_ptr<CommonStructuredDataDef>> m_defs;
|
||||
|
||||
CommonStructuredDataDef* m_current_def;
|
||||
CommonStructuredDataEnum* m_current_enum;
|
||||
CommonStructuredDataStruct* m_current_struct;
|
||||
size_t m_current_struct_offset_in_bits;
|
||||
|
||||
std::map<std::string, CommonStructuredDataType> m_def_types_by_name;
|
||||
std::map<CommonStructuredDataIndexedArray, size_t> m_def_indexed_arrays;
|
||||
std::map<CommonStructuredDataEnumedArray, size_t> m_def_enumed_arrays;
|
||||
|
||||
StructuredDataDefParserState();
|
||||
};
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
#include "StructuredDataDefReader.h"
|
||||
|
||||
#include "StructuredDataDefParser.h"
|
||||
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
||||
#include "Parsing/Impl/DefinesStreamProxy.h"
|
||||
#include "Parsing/Impl/IncludingStreamProxy.h"
|
||||
#include "Parsing/Impl/ParserMultiInputStream.h"
|
||||
#include "Parsing/Impl/ParserSingleInputStream.h"
|
||||
|
||||
using namespace sdd;
|
||||
|
||||
StructuredDataDefReader::StructuredDataDefReader(std::istream& stream, std::string fileName)
|
||||
: StructuredDataDefReader(stream, std::move(fileName), nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
StructuredDataDefReader::StructuredDataDefReader(std::istream& stream, std::string fileName, include_callback_t includeCallback)
|
||||
: m_file_name(std::move(fileName)),
|
||||
m_stream(nullptr)
|
||||
{
|
||||
OpenBaseStream(stream, std::move(includeCallback));
|
||||
SetupStreamProxies();
|
||||
m_stream = m_open_streams.back().get();
|
||||
}
|
||||
|
||||
bool StructuredDataDefReader::OpenBaseStream(std::istream& stream, include_callback_t includeCallback)
|
||||
{
|
||||
if (includeCallback)
|
||||
m_open_streams.emplace_back(std::make_unique<ParserMultiInputStream>(stream, m_file_name, std::move(includeCallback)));
|
||||
else
|
||||
m_open_streams.emplace_back(std::make_unique<ParserSingleInputStream>(stream, m_file_name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void StructuredDataDefReader::SetupStreamProxies()
|
||||
{
|
||||
m_open_streams.emplace_back(std::make_unique<CommentRemovingStreamProxy>(m_open_streams.back().get()));
|
||||
m_open_streams.emplace_back(std::make_unique<IncludingStreamProxy>(m_open_streams.back().get()));
|
||||
m_open_streams.emplace_back(std::make_unique<DefinesStreamProxy>(m_open_streams.back().get()));
|
||||
|
||||
m_stream = m_open_streams.back().get();
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<CommonStructuredDataDef>> StructuredDataDefReader::ReadStructureDataDefs(bool& success)
|
||||
{
|
||||
SimpleLexer::Config lexerConfig;
|
||||
lexerConfig.m_emit_new_line_tokens = false;
|
||||
lexerConfig.m_read_strings = true;
|
||||
lexerConfig.m_read_numbers = true;
|
||||
const auto lexer = std::make_unique<SimpleLexer>(m_stream, std::move(lexerConfig));
|
||||
|
||||
const auto parser = std::make_unique<StructuredDataDefParser>(lexer.get());
|
||||
|
||||
success = parser->Parse();
|
||||
if (success)
|
||||
return parser->GetDefs();
|
||||
|
||||
std::cout << "Parsing structured data def file \"" << m_file_name << "\" failed!" << std::endl;
|
||||
return {};
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "StructuredDataDef/CommonStructuredDataDef.h"
|
||||
#include "Parsing/IParserLineStream.h"
|
||||
|
||||
class StructuredDataDefReader
|
||||
{
|
||||
public:
|
||||
using include_callback_t = std::function<std::unique_ptr<std::istream>(const std::string& filename, const std::string& sourceFile)>;
|
||||
|
||||
private:
|
||||
std::string m_file_name;
|
||||
IParserLineStream* m_stream;
|
||||
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
|
||||
|
||||
bool OpenBaseStream(std::istream& stream, include_callback_t includeCallback);
|
||||
void SetupStreamProxies();
|
||||
|
||||
public:
|
||||
StructuredDataDefReader(std::istream& stream, std::string fileName);
|
||||
StructuredDataDefReader(std::istream& stream, std::string fileName, include_callback_t includeCallback);
|
||||
|
||||
std::vector<std::unique_ptr<CommonStructuredDataDef>> ReadStructureDataDefs(bool& success);
|
||||
};
|
Reference in New Issue
Block a user