Parse StructuredDataDef structs

This commit is contained in:
Jan 2022-01-19 19:58:41 +01:00
parent 1c1fbd1007
commit 944586fcde
5 changed files with 283 additions and 14 deletions

View File

@ -18,6 +18,30 @@ CommonStructuredDataDefType::CommonStructuredDataDefType(const CommonStructuredD
{
}
bool operator<(const CommonStructuredDataDefType& lhs, const CommonStructuredDataDefType& rhs)
{
if (lhs.m_category < rhs.m_category)
return true;
if (rhs.m_category < lhs.m_category)
return false;
return lhs.m_info.type_index < rhs.m_info.type_index;
}
bool operator<=(const CommonStructuredDataDefType& lhs, const CommonStructuredDataDefType& rhs)
{
return !(rhs < lhs);
}
bool operator>(const CommonStructuredDataDefType& lhs, const CommonStructuredDataDefType& rhs)
{
return rhs < lhs;
}
bool operator>=(const CommonStructuredDataDefType& lhs, const CommonStructuredDataDefType& rhs)
{
return !(lhs < rhs);
}
CommonStructuredDataDefIndexedArray::CommonStructuredDataDefIndexedArray()
: m_array_size(0u)
{
@ -29,6 +53,30 @@ CommonStructuredDataDefIndexedArray::CommonStructuredDataDefIndexedArray(const C
{
}
bool operator<(const CommonStructuredDataDefIndexedArray& lhs, const CommonStructuredDataDefIndexedArray& rhs)
{
if (lhs.m_array_type < rhs.m_array_type)
return true;
if (rhs.m_array_type < lhs.m_array_type)
return false;
return lhs.m_array_size < rhs.m_array_size;
}
bool operator<=(const CommonStructuredDataDefIndexedArray& lhs, const CommonStructuredDataDefIndexedArray& rhs)
{
return !(rhs < lhs);
}
bool operator>(const CommonStructuredDataDefIndexedArray& lhs, const CommonStructuredDataDefIndexedArray& rhs)
{
return rhs < lhs;
}
bool operator>=(const CommonStructuredDataDefIndexedArray& lhs, const CommonStructuredDataDefIndexedArray& rhs)
{
return !(lhs < rhs);
}
CommonStructuredDataDefEnumedArray::CommonStructuredDataDefEnumedArray()
: m_enum_index(0u)
{
@ -39,3 +87,27 @@ CommonStructuredDataDefEnumedArray::CommonStructuredDataDefEnumedArray(const Com
m_enum_index(enumIndex)
{
}
bool operator<(const CommonStructuredDataDefEnumedArray& lhs, const CommonStructuredDataDefEnumedArray& rhs)
{
if (lhs.m_array_type < rhs.m_array_type)
return true;
if (rhs.m_array_type < lhs.m_array_type)
return false;
return lhs.m_enum_index < rhs.m_enum_index;
}
bool operator<=(const CommonStructuredDataDefEnumedArray& lhs, const CommonStructuredDataDefEnumedArray& rhs)
{
return !(rhs < lhs);
}
bool operator>(const CommonStructuredDataDefEnumedArray& lhs, const CommonStructuredDataDefEnumedArray& rhs)
{
return rhs < lhs;
}
bool operator>=(const CommonStructuredDataDefEnumedArray& lhs, const CommonStructuredDataDefEnumedArray& rhs)
{
return !(lhs < rhs);
}

View File

@ -8,9 +8,9 @@ enum class CommonStructuredDataDefTypeCategory
INT,
BYTE,
BOOL,
STRING,
FLOAT,
SHORT,
STRING,
ENUM,
STRUCT,
INDEXED_ARRAY,
@ -31,6 +31,11 @@ struct CommonStructuredDataDefType
CommonStructuredDataDefType();
explicit CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory category);
CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory category, size_t extraInfo);
friend bool operator<(const CommonStructuredDataDefType& lhs, const CommonStructuredDataDefType& rhs);
friend bool operator<=(const CommonStructuredDataDefType& lhs, const CommonStructuredDataDefType& rhs);
friend bool operator>(const CommonStructuredDataDefType& lhs, const CommonStructuredDataDefType& rhs);
friend bool operator>=(const CommonStructuredDataDefType& lhs, const CommonStructuredDataDefType& rhs);
};
struct CommonStructuredDataDefIndexedArray
@ -40,6 +45,11 @@ struct CommonStructuredDataDefIndexedArray
CommonStructuredDataDefIndexedArray();
CommonStructuredDataDefIndexedArray(CommonStructuredDataDefType type, size_t arraySize);
friend bool operator<(const CommonStructuredDataDefIndexedArray& lhs, const CommonStructuredDataDefIndexedArray& rhs);
friend bool operator<=(const CommonStructuredDataDefIndexedArray& lhs, const CommonStructuredDataDefIndexedArray& rhs);
friend bool operator>(const CommonStructuredDataDefIndexedArray& lhs, const CommonStructuredDataDefIndexedArray& rhs);
friend bool operator>=(const CommonStructuredDataDefIndexedArray& lhs, const CommonStructuredDataDefIndexedArray& rhs);
};
struct CommonStructuredDataDefEnumedArray
@ -49,4 +59,9 @@ struct CommonStructuredDataDefEnumedArray
CommonStructuredDataDefEnumedArray();
CommonStructuredDataDefEnumedArray(CommonStructuredDataDefType type, size_t enumIndex);
friend bool operator<(const CommonStructuredDataDefEnumedArray& lhs, const CommonStructuredDataDefEnumedArray& rhs);
friend bool operator<=(const CommonStructuredDataDefEnumedArray& lhs, const CommonStructuredDataDefEnumedArray& rhs);
friend bool operator>(const CommonStructuredDataDefEnumedArray& lhs, const CommonStructuredDataDefEnumedArray& rhs);
friend bool operator>=(const CommonStructuredDataDefEnumedArray& lhs, const CommonStructuredDataDefEnumedArray& rhs);
};

View File

@ -27,6 +27,7 @@ namespace sdd::def_scope_sequences
auto newEnum = std::make_unique<CommonStructuredDataDefEnum>(result.NextCapture(CAPTURE_NAME).IdentifierValue());
state->m_current_enum = newEnum.get();
state->m_def_types_by_name.emplace(newEnum->m_name, CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory::ENUM, state->m_current_def->m_enums.size()));
state->m_current_def->m_enums.emplace_back(std::move(newEnum));
}
};
@ -53,8 +54,15 @@ namespace sdd::def_scope_sequences
assert(state->m_current_def);
auto newStruct = std::make_unique<CommonStructuredDataDefStruct>(result.NextCapture(CAPTURE_NAME).IdentifierValue());
state->m_current_struct = newStruct.get();
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, CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory::STRUCT, newStructIndex));
state->m_current_def->m_structs.emplace_back(std::move(newStruct));
if(newStructPtr->m_name == "root")
state->m_current_def->m_root_type = CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory::STRUCT, newStructIndex);
}
};
@ -79,6 +87,9 @@ namespace sdd::def_scope_sequences
assert(state->m_current_struct == nullptr);
state->m_current_def = nullptr;
state->m_def_types_by_name.clear();
state->m_def_indexed_arrays.clear();
state->m_def_enumed_arrays.clear();
}
};
}
@ -94,6 +105,7 @@ StructuredDataDefDefScopeSequences::StructuredDataDefDefScopeSequences(std::vect
void StructuredDataDefDefScopeSequences::AddSequences() const
{
AddSequence(std::make_unique<SequenceCloseScope>());
AddSequence(std::make_unique<SequenceEnum>());
AddSequence(std::make_unique<SequenceStruct>());
}

View File

@ -4,30 +4,194 @@
namespace sdd::struct_scope_sequences
{
class SequenceVersion final : public StructuredDataDefParser::sequence_t
class SequenceStructEntry final : public StructuredDataDefParser::sequence_t
{
static constexpr auto CAPTURE_VERSION = 1;
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 TAG_ARRAY = 8;
static constexpr auto TAG_ARRAY_INDEX = 9;
static constexpr auto TAG_ARRAY_ENUM = 10;
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 constexpr auto CAPTURE_ARRAY_ENUM = 5;
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().Tag(TAG_ARRAY_INDEX).Capture(CAPTURE_ARRAY_SIZE),
create.Identifier().Tag(TAG_ARRAY_ENUM).Capture(CAPTURE_ARRAY_ENUM)
}),
create.Char(']')
}).Tag(TAG_ARRAY);
}
public:
SequenceVersion()
SequenceStructEntry()
{
const SimpleMatcherFactory create(this);
AddMatchers({
create.Keyword("version"),
create.Integer().Capture(CAPTURE_VERSION),
create.Char('{')
TypeMatchers(create),
create.Identifier().Capture(CAPTURE_ENTRY_NAME),
create.OptionalLoop(ArrayMatchers(create)),
create.Char(';')
});
}
private:
static CommonStructuredDataDefType ProcessType(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result)
{
const auto typeTag = result.NextTag();
switch (typeTag)
{
case TAG_TYPE_INT:
return CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory::INT);
case TAG_TYPE_BYTE:
return CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory::BYTE);
case TAG_TYPE_BOOL:
return CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory::BOOL);
case TAG_TYPE_FLOAT:
return CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory::FLOAT);
case TAG_TYPE_SHORT:
return CommonStructuredDataDefType(CommonStructuredDataDefTypeCategory::SHORT);
case TAG_TYPE_STRING:
{
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");
return {CommonStructuredDataDefTypeCategory::STRING, static_cast<size_t>(stringLength)};
}
case TAG_TYPE_NAMED:
{
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");
return existingType->second;
}
default:
throw ParsingException(TokenPos(), "Invalid Tag for Type @ ProcessType!!!");
}
}
static CommonStructuredDataDefType ProcessArray(StructuredDataDefParserState* state, SequenceResult<SimpleParserValue>& result, CommonStructuredDataDefType currentType)
{
const auto arrayTag = result.NextTag();
if (arrayTag == TAG_ARRAY_INDEX)
{
const auto& arraySizeToken = result.NextCapture(CAPTURE_ARRAY_SIZE);
const auto arraySize = arraySizeToken.IntegerValue();
if (arraySize <= 0)
throw ParsingException(arraySizeToken.GetPos(), "Array size must be greater than zero");
const CommonStructuredDataDefIndexedArray indexedArray(currentType, arraySize);
const auto existingIndexedArray = state->m_def_indexed_arrays.find(indexedArray);
if (existingIndexedArray != state->m_def_indexed_arrays.end())
return {CommonStructuredDataDefTypeCategory::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 {CommonStructuredDataDefTypeCategory::INDEXED_ARRAY, newIndexedArrayIndex};
}
if (arrayTag == TAG_ARRAY_ENUM)
{
const auto& enumNameToken = result.NextCapture(CAPTURE_ARRAY_ENUM);
const auto enumName = enumNameToken.IdentifierValue();
const auto existingType = state->m_def_types_by_name.find(enumName);
if (existingType == state->m_def_types_by_name.end())
throw ParsingException(enumNameToken.GetPos(), "No type defined under this name");
if (existingType->second.m_category != CommonStructuredDataDefTypeCategory::ENUM)
throw ParsingException(enumNameToken.GetPos(), "Type for enumed array must be an enum");
const CommonStructuredDataDefEnumedArray 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 {CommonStructuredDataDefTypeCategory::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 {CommonStructuredDataDefTypeCategory::ENUM_ARRAY, newEnumedArrayIndex};
}
throw ParsingException(TokenPos(), "Invalid Tag 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);
auto currentType = ProcessType(state, result);
while (result.PeekAndRemoveIfTag(TAG_ARRAY) == TAG_ARRAY)
currentType = ProcessArray(state, result, currentType);
// TODO: Calculate offset
state->m_current_struct->m_entries.emplace_back(result.NextCapture(CAPTURE_ENTRY_NAME).IdentifierValue(), currentType, 0);
}
};
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
{
auto newDef = std::make_unique<CommonStructuredDataDef>();
newDef->m_version = result.NextCapture(CAPTURE_VERSION).IntegerValue();
assert(state->m_current_struct != nullptr);
state->m_current_def = newDef.get();
state->m_defs.emplace_back(std::move(newDef));
state->m_current_struct = nullptr;
}
};
}
@ -43,5 +207,6 @@ StructuredDataDefStructScopeSequences::StructuredDataDefStructScopeSequences(std
void StructuredDataDefStructScopeSequences::AddSequences() const
{
AddSequence(std::make_unique<SequenceVersion>());
AddSequence(std::make_unique<SequenceCloseStruct>());
AddSequence(std::make_unique<SequenceStructEntry>());
}

View File

@ -1,4 +1,5 @@
#pragma once
#include <map>
#include <memory>
#include <vector>
@ -15,6 +16,10 @@ namespace sdd
CommonStructuredDataDefEnum* m_current_enum;
CommonStructuredDataDefStruct* m_current_struct;
std::map<std::string, CommonStructuredDataDefType> m_def_types_by_name;
std::map<CommonStructuredDataDefIndexedArray, size_t> m_def_indexed_arrays;
std::map<CommonStructuredDataDefEnumedArray, size_t> m_def_enumed_arrays;
StructuredDataDefParserState();
};
}