parse variables

This commit is contained in:
Jan 2021-02-19 00:39:33 +01:00
parent cce9494856
commit e51babaeb4
10 changed files with 123 additions and 9 deletions

View File

@ -5,10 +5,11 @@
#include "IHeaderBlock.h" #include "IHeaderBlock.h"
#include "IHeaderBlockNameHolder.h" #include "IHeaderBlockNameHolder.h"
#include "IHeaderBlockVariableDefining.h" #include "IHeaderBlockVariableDefining.h"
#include "IHeaderBlockVariableHolder.h"
#include "Domain/Definition/StructDefinition.h" #include "Domain/Definition/StructDefinition.h"
#include "Domain/Definition/Variable.h" #include "Domain/Definition/Variable.h"
class HeaderBlockStruct final : public IHeaderBlock, public IHeaderBlockNameHolder, public IHeaderBlockVariableDefining class HeaderBlockStruct final : public IHeaderBlock, public IHeaderBlockNameHolder, public IHeaderBlockVariableDefining, public IHeaderBlockVariableHolder
{ {
std::string m_namespace; std::string m_namespace;
std::string m_type_name; std::string m_type_name;
@ -32,7 +33,7 @@ public:
void OnClose(HeaderParserState* state) override; void OnClose(HeaderParserState* state) override;
void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override; void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override;
void AddVariable(std::shared_ptr<Variable> variable); void AddVariable(std::shared_ptr<Variable> variable) override;
void SetCustomAlignment(int alignment); void SetCustomAlignment(int alignment);
void Inherit(const StructDefinition* parentStruct); void Inherit(const StructDefinition* parentStruct);

View File

@ -3,8 +3,9 @@
#include "IHeaderBlock.h" #include "IHeaderBlock.h"
#include "IHeaderBlockNameHolder.h" #include "IHeaderBlockNameHolder.h"
#include "IHeaderBlockVariableDefining.h" #include "IHeaderBlockVariableDefining.h"
#include "IHeaderBlockVariableHolder.h"
class HeaderBlockUnion final : public IHeaderBlock, public IHeaderBlockNameHolder, public IHeaderBlockVariableDefining class HeaderBlockUnion final : public IHeaderBlock, public IHeaderBlockNameHolder, public IHeaderBlockVariableDefining, public IHeaderBlockVariableHolder
{ {
std::string m_namespace; std::string m_namespace;
std::string m_type_name; std::string m_type_name;
@ -28,7 +29,7 @@ public:
void OnClose(HeaderParserState* state) override; void OnClose(HeaderParserState* state) override;
void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override; void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override;
void AddVariable(std::shared_ptr<Variable> variable); void AddVariable(std::shared_ptr<Variable> variable) override;
void SetCustomAlignment(int alignment); void SetCustomAlignment(int alignment);
void Inherit(const StructDefinition* parentStruct); void Inherit(const StructDefinition* parentStruct);

View File

@ -0,0 +1,18 @@
#pragma once
#include <memory>
#include "Domain/Definition/Variable.h"
class IHeaderBlockVariableHolder
{
public:
IHeaderBlockVariableHolder() = default;
virtual ~IHeaderBlockVariableHolder() = default;
IHeaderBlockVariableHolder(const IHeaderBlockVariableHolder& other) = default;
IHeaderBlockVariableHolder(IHeaderBlockVariableHolder&& other) noexcept = default;
IHeaderBlockVariableHolder& operator=(const IHeaderBlockVariableHolder& other) = default;
IHeaderBlockVariableHolder& operator=(IHeaderBlockVariableHolder&& other) noexcept = default;
virtual void AddVariable(std::shared_ptr<Variable> variable) = 0;
};

View File

@ -1,6 +1,5 @@
#include "SequenceTypedef.h" #include "SequenceTypedef.h"
#include "Domain/Definition/ArrayDeclarationModifier.h" #include "Domain/Definition/ArrayDeclarationModifier.h"
#include "Domain/Definition/PointerDeclarationModifier.h" #include "Domain/Definition/PointerDeclarationModifier.h"
#include "Parsing/Header/Matcher/HeaderMatcherFactory.h" #include "Parsing/Header/Matcher/HeaderMatcherFactory.h"

View File

@ -1,5 +1,8 @@
#include "SequenceVariable.h" #include "SequenceVariable.h"
#include "Domain/Definition/ArrayDeclarationModifier.h"
#include "Domain/Definition/PointerDeclarationModifier.h"
#include "Parsing/Header/Block/IHeaderBlockVariableHolder.h"
#include "Parsing/Header/Matcher/HeaderMatcherFactory.h" #include "Parsing/Header/Matcher/HeaderMatcherFactory.h"
#include "Parsing/Header/Matcher/HeaderCommonMatchers.h" #include "Parsing/Header/Matcher/HeaderCommonMatchers.h"
@ -38,11 +41,80 @@ SequenceVariable::SequenceVariable()
}, LABEL_POINTER_TO_ARRAY); }, LABEL_POINTER_TO_ARRAY);
AddMatchers(create.Or({ AddMatchers(create.Or({
create.Label(LABEL_ARRAY_OF_POINTERS), create.Label(LABEL_ARRAY_OF_POINTERS).Tag(TAG_ARRAY_OF_POINTERS),
create.Label(LABEL_POINTER_TO_ARRAY) create.Label(LABEL_POINTER_TO_ARRAY).Tag(TAG_POINTER_TO_ARRAY)
})); }));
} }
void SequenceVariable::AddPointerDeclarationModifiers(SequenceResult<HeaderParserValue>& result, TypeDeclaration* typeDeclaration) const
{
while (result.PeekAndRemoveIfTag(TAG_POINTER) == TAG_POINTER)
typeDeclaration->m_declaration_modifiers.emplace_back(std::make_unique<PointerDeclarationModifier>());
}
void SequenceVariable::AddArrayDeclarationModifiers(HeaderParserState* state, SequenceResult<HeaderParserValue>& result, TypeDeclaration* typeDeclaration) const
{
while (result.HasNextCapture(CAPTURE_ARRAY))
{
const auto& arrayToken = result.NextCapture(CAPTURE_ARRAY);
if (arrayToken.m_type == HeaderParserValueType::INTEGER)
{
typeDeclaration->m_declaration_modifiers.emplace_back(std::make_unique<ArrayDeclarationModifier>(arrayToken.IntegerValue()));
}
else
{
auto* enumMember = state->FindEnumMember(arrayToken.IdentifierValue());
if (enumMember == nullptr)
throw ParsingException(arrayToken.GetPos(), "Unknown enum member");
typeDeclaration->m_declaration_modifiers.emplace_back(std::make_unique<ArrayDeclarationModifier>(enumMember->m_value));
}
}
}
void SequenceVariable::ProcessMatch(HeaderParserState* state, SequenceResult<HeaderParserValue>& result) const void SequenceVariable::ProcessMatch(HeaderParserState* state, SequenceResult<HeaderParserValue>& result) const
{ {
auto* variableHolder = dynamic_cast<IHeaderBlockVariableHolder*>(state->GetBlock());
if (variableHolder == nullptr)
throw ParsingException(TokenPos(), "Defining variable in non VariableHolder block");
const auto modeTag = result.NextTag();
assert(modeTag == TAG_ARRAY_OF_POINTERS || modeTag == TAG_POINTER_TO_ARRAY);
const auto name = result.NextCapture(CAPTURE_NAME).IdentifierValue();
const auto& typenameToken = result.NextCapture(CAPTURE_TYPE);
const auto* type = state->FindType(typenameToken.TypeNameValue());
if (type == nullptr && !state->m_namespace.IsEmpty())
{
const auto fullTypename = NamespaceBuilder::Combine(state->m_namespace.ToString(), typenameToken.TypeNameValue());
type = state->FindType(fullTypename);
}
if (type == nullptr)
throw ParsingException(typenameToken.GetPos(), "Unknown type");
auto variable = std::make_shared<Variable>(name, std::make_unique<TypeDeclaration>(type));
variable->m_type_declaration->m_is_const = result.PeekAndRemoveIfTag(TAG_CONST) == TAG_CONST;
if (result.HasNextCapture(CAPTURE_ALIGN))
{
const auto& alignToken = result.NextCapture(CAPTURE_ALIGN);
variable->m_alignment_override = static_cast<unsigned>(alignToken.IntegerValue());
variable->m_has_alignment_override = true;
}
if (modeTag == TAG_ARRAY_OF_POINTERS)
{
AddArrayDeclarationModifiers(state, result, variable->m_type_declaration.get());
AddPointerDeclarationModifiers(result, variable->m_type_declaration.get());
}
else
{
AddPointerDeclarationModifiers(result, variable->m_type_declaration.get());
AddArrayDeclarationModifiers(state, result, variable->m_type_declaration.get());
}
variableHolder->AddVariable(std::move(variable));
} }

View File

@ -21,6 +21,9 @@ class SequenceVariable final : public HeaderParser::sequence_t
static constexpr auto LABEL_ARRAY_OF_POINTERS = 1; static constexpr auto LABEL_ARRAY_OF_POINTERS = 1;
static constexpr auto LABEL_POINTER_TO_ARRAY = 2; static constexpr auto LABEL_POINTER_TO_ARRAY = 2;
void AddPointerDeclarationModifiers(SequenceResult<HeaderParserValue>& result, TypeDeclaration* typeDeclaration) const;
void AddArrayDeclarationModifiers(HeaderParserState* state, SequenceResult<HeaderParserValue>& result, TypeDeclaration* typeDeclaration) const;
protected: protected:
void ProcessMatch(HeaderParserState* state, SequenceResult<HeaderParserValue>& result) const override; void ProcessMatch(HeaderParserState* state, SequenceResult<HeaderParserValue>& result) const override;

View File

@ -68,7 +68,7 @@ public:
return result; return result;
if (m_tag_id != NO_ID) if (m_tag_id != NO_ID)
result.m_tags.push_back(m_tag_id); result.m_tags.insert(result.m_tags.begin(), m_tag_id);
if (m_transform_func) if (m_transform_func)
{ {

View File

@ -2,6 +2,7 @@
#include "Parsing/Header/Sequence/SequenceNamespace.h" #include "Parsing/Header/Sequence/SequenceNamespace.h"
#include "Parsing/Mock/MockLexer.h" #include "Parsing/Mock/MockLexer.h"
#include "Parsing/Mock/MockPackValueSupplier.h"
namespace test::parsing::header::sequence::sequence_namespace namespace test::parsing::header::sequence::sequence_namespace
{ {
@ -15,8 +16,9 @@ namespace test::parsing::header::sequence::sequence_namespace
HeaderParserValue::Character(pos, '{') HeaderParserValue::Character(pos, '{')
}, HeaderParserValue::EndOfFile(pos))); }, HeaderParserValue::EndOfFile(pos)));
const auto packValueSupplier = std::make_unique<MockPackValueSupplier>();
const auto sequence = std::make_unique<SequenceNamespace>(); const auto sequence = std::make_unique<SequenceNamespace>();
const auto state = std::make_unique<HeaderParserState>(); const auto state = std::make_unique<HeaderParserState>(packValueSupplier.get());
unsigned consumedTokenCount; unsigned consumedTokenCount;
auto result = sequence->MatchSequence(lexer.get(), state.get(), consumedTokenCount); auto result = sequence->MatchSequence(lexer.get(), state.get(), consumedTokenCount);

View File

@ -0,0 +1,8 @@
#include "MockPackValueSupplier.h"
#include "Parsing/Impl/PackDefinitionStreamProxy.h"
int MockPackValueSupplier::GetCurrentPack() const
{
return PackDefinitionStreamProxy::DEFAULT_PACK;
}

View File

@ -0,0 +1,10 @@
#pragma once
#include "Utils/ClassUtils.h"
#include "Parsing/IPackValueSupplier.h"
class MockPackValueSupplier final : public IPackValueSupplier
{
public:
_NODISCARD int GetCurrentPack() const override;
};