Set closing block variable names

This commit is contained in:
Jan 2021-02-18 15:59:22 +01:00
parent bb877f87bb
commit 3c1599c1a0
11 changed files with 96 additions and 13 deletions

View File

@ -11,7 +11,7 @@ HeaderBlockType HeaderBlockEnum::GetType()
const std::vector<IHeaderBlock::sequence_t*>& HeaderBlockEnum::GetTestsForBlock()
{
static std::vector<sequence_t*> tests({
new SequenceCloseBlock(),
new SequenceCloseBlock(true),
new SequenceEnumMember()
});
@ -29,3 +29,8 @@ void HeaderBlockEnum::OnClose(HeaderParserState* state)
void HeaderBlockEnum::OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block)
{
}
void HeaderBlockEnum::SetVariableName(std::string name)
{
m_variable_name = std::move(name);
}

View File

@ -1,13 +1,18 @@
#pragma once
#include "IHeaderBlock.h"
#include "IHeaderBlockVariableDefining.h"
class HeaderBlockEnum final : public IHeaderBlock
class HeaderBlockEnum final : public IHeaderBlock, public IHeaderBlockVariableDefining
{
std::string m_variable_name;
public:
HeaderBlockType GetType() override;
const std::vector<sequence_t*>& GetTestsForBlock() override;
void OnOpen(HeaderParserState* state) override;
void OnClose(HeaderParserState* state) override;
void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override;
void SetVariableName(std::string name) override;
};

View File

@ -21,7 +21,7 @@ HeaderBlockType HeaderBlockNamespace::GetType()
const std::vector<IHeaderBlock::sequence_t*>& HeaderBlockNamespace::GetTestsForBlock()
{
static std::vector<sequence_t*> tests({
new SequenceCloseBlock(),
new SequenceCloseBlock(false),
new SequenceEnum(),
new SequenceForwardDecl(),
new SequenceNamespace(),

View File

@ -14,7 +14,7 @@ HeaderBlockType HeaderBlockStruct::GetType()
const std::vector<IHeaderBlock::sequence_t*>& HeaderBlockStruct::GetTestsForBlock()
{
static std::vector<sequence_t*> tests({
new SequenceCloseBlock(),
new SequenceCloseBlock(true),
new SequenceEnum(),
new SequenceStruct(),
new SequenceUnion(),
@ -35,3 +35,8 @@ void HeaderBlockStruct::OnClose(HeaderParserState* state)
void HeaderBlockStruct::OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block)
{
}
void HeaderBlockStruct::SetVariableName(std::string name)
{
m_variable_name = std::move(name);
}

View File

@ -1,13 +1,18 @@
#pragma once
#include "IHeaderBlock.h"
#include "IHeaderBlockVariableDefining.h"
class HeaderBlockStruct final : public IHeaderBlock
class HeaderBlockStruct final : public IHeaderBlock, public IHeaderBlockVariableDefining
{
std::string m_variable_name;
public:
HeaderBlockType GetType() override;
const std::vector<sequence_t*>& GetTestsForBlock() override;
void OnOpen(HeaderParserState* state) override;
void OnClose(HeaderParserState* state) override;
void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override;
void SetVariableName(std::string name) override;
};

View File

@ -14,7 +14,7 @@ HeaderBlockType HeaderBlockUnion::GetType()
const std::vector<IHeaderBlock::sequence_t*>& HeaderBlockUnion::GetTestsForBlock()
{
static std::vector<sequence_t*> tests({
new SequenceCloseBlock(),
new SequenceCloseBlock(true),
new SequenceEnum(),
new SequenceStruct(),
new SequenceUnion(),
@ -35,3 +35,8 @@ void HeaderBlockUnion::OnClose(HeaderParserState* state)
void HeaderBlockUnion::OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block)
{
}
void HeaderBlockUnion::SetVariableName(std::string name)
{
m_variable_name = std::move(name);
}

View File

@ -1,13 +1,18 @@
#pragma once
#include "IHeaderBlock.h"
#include "IHeaderBlockVariableDefining.h"
class HeaderBlockUnion final : public IHeaderBlock
class HeaderBlockUnion final : public IHeaderBlock, public IHeaderBlockVariableDefining
{
std::string m_variable_name;
public:
HeaderBlockType GetType() override;
const std::vector<sequence_t*>& GetTestsForBlock() override;
void OnOpen(HeaderParserState* state) override;
void OnClose(HeaderParserState* state) override;
void OnChildBlockClose(HeaderParserState* state, IHeaderBlock* block) override;
void SetVariableName(std::string name) override;
};

View File

@ -0,0 +1,16 @@
#pragma once
#include <string>
class IHeaderBlockVariableDefining
{
public:
IHeaderBlockVariableDefining() = default;
virtual ~IHeaderBlockVariableDefining() = default;
IHeaderBlockVariableDefining(const IHeaderBlockVariableDefining& other) = default;
IHeaderBlockVariableDefining(IHeaderBlockVariableDefining&& other) noexcept = default;
IHeaderBlockVariableDefining& operator=(const IHeaderBlockVariableDefining& other) = default;
IHeaderBlockVariableDefining& operator=(IHeaderBlockVariableDefining&& other) noexcept = default;
virtual void SetVariableName(std::string name) = 0;
};

View File

@ -1,14 +1,16 @@
#include "SequenceCloseBlock.h"
#include "Parsing/Header/Block/IHeaderBlockVariableDefining.h"
#include "Parsing/Header/Matcher/HeaderMatcherFactory.h"
#include "Parsing/Header/Matcher/HeaderCommonMatchers.h"
SequenceCloseBlock::SequenceCloseBlock()
SequenceCloseBlock::SequenceCloseBlock(const bool semicolonRequired)
: m_semicolon_required(semicolonRequired)
{
const HeaderMatcherFactory create(this);
AddMatchers({
create.Char('}'),
create.Char('}').Capture(CAPTURE_CLOSING_PARENTHESIS),
create.Optional(create.And({
create.Optional(create.Identifier().Capture(CAPTURE_NAME)),
create.Char(';').Tag(TAG_SEMICOLON)
@ -18,6 +20,27 @@ SequenceCloseBlock::SequenceCloseBlock()
void SequenceCloseBlock::ProcessMatch(HeaderParserState* state, SequenceResult<HeaderParserValue>& result) const
{
// TODO: Set variable name to last block
if (result.NextTag() == TAG_SEMICOLON)
{
if(!m_semicolon_required)
throw ParsingException(result.NextCapture(CAPTURE_CLOSING_PARENTHESIS).GetPos(), "Block should not be closed with semicolon");
}
else
{
if (m_semicolon_required)
throw ParsingException(result.NextCapture(CAPTURE_CLOSING_PARENTHESIS).GetPos(), "Block must be closed with semicolon");
}
if (result.HasNextCapture(CAPTURE_NAME))
{
auto* variableDefiningBlock = dynamic_cast<IHeaderBlockVariableDefining*>(state->GetBlock());
const auto& name = result.NextCapture(CAPTURE_NAME);
if (variableDefiningBlock == nullptr)
throw ParsingException(name.GetPos(), "Block does not support holding names.");
variableDefiningBlock->SetVariableName(name.IdentifierValue());
}
state->PopBlock();
}

View File

@ -10,10 +10,13 @@ class SequenceCloseBlock final : public HeaderParser::sequence_t
static constexpr auto TAG_SEMICOLON = 1;
static constexpr auto CAPTURE_NAME = 1;
static constexpr auto CAPTURE_CLOSING_PARENTHESIS = 2;
bool m_semicolon_required;
protected:
void ProcessMatch(HeaderParserState* state, SequenceResult<HeaderParserValue>& result) const override;
public:
SequenceCloseBlock();
explicit SequenceCloseBlock(bool semicolonRequired);
};

View File

@ -30,7 +30,7 @@ protected:
virtual const std::vector<sequence_t*>& GetTestsForState() = 0;
public:
virtual ~AbstractParser() = default;
virtual ~AbstractParser() override = default;
AbstractParser(const AbstractParser& other) = default;
AbstractParser(AbstractParser&& other) noexcept = default;
AbstractParser& operator=(const AbstractParser& other) = default;
@ -77,7 +77,18 @@ public:
}
catch (const ParsingException& e)
{
std::cout << "Error: " << e.FullMessage() << std::endl;
const auto pos = e.Position();
const auto line = m_lexer->GetLineForPos(pos);
if (!line.IsEof())
{
std::cout << "Error: " << e.FullMessage() << "\n" << line.m_line.substr(pos.m_column - 1) << std::endl;
}
else
{
std::cout << "Error: " << e.FullMessage() << std::endl;
}
return false;
}