Add basic parsing for menu lists with only loadMenus instructions

This commit is contained in:
Jan
2021-10-31 15:37:46 +01:00
parent 037e13b874
commit bba55706bf
27 changed files with 602 additions and 1 deletions

View File

@ -0,0 +1,67 @@
#include "SequenceCloseBlock.h"
#include <sstream>
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
SequenceCloseBlock::SequenceCloseBlock()
{
const SimpleMatcherFactory create(this);
AddMatchers({
create.Char('}').Capture(CAPTURE_TOKEN)
});
}
void SequenceCloseBlock::ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const
{
assert(state->m_current_item || state->m_current_menu || state->m_current_function || state->m_in_global_scope);
assert(!state->m_current_item || (state->m_current_item && state->m_current_menu));
if(state->m_current_item && state->m_current_menu)
{
state->m_current_menu->m_items.emplace_back(std::move(state->m_current_item));
state->m_current_item = nullptr;
}
else if(state->m_current_menu)
{
if(state->m_current_menu->m_name.empty())
throw ParsingException(result.NextCapture(CAPTURE_TOKEN).GetPos(), "Menu must have a name");
const auto existingMenu = state->m_menus_by_name.find(state->m_current_menu->m_name);
if(existingMenu == state->m_menus_by_name.end())
{
state->m_menus_by_name.emplace(std::make_pair(state->m_current_menu->m_name, state->m_current_menu.get()));
state->m_menus.emplace_back(std::move(state->m_current_menu));
state->m_current_menu = nullptr;
}
else
{
std::ostringstream ss;
ss << "Menu with name \"" << state->m_current_menu->m_name << "\" already exists";
throw ParsingException(result.NextCapture(CAPTURE_TOKEN).GetPos(), ss.str());
}
}
else if(state->m_current_function)
{
const auto existingFunction = state->m_functions_by_name.find(state->m_current_function->m_name);
if (existingFunction == state->m_functions_by_name.end())
{
state->m_functions_by_name.emplace(std::make_pair(state->m_current_function->m_name, state->m_current_function.get()));
state->m_functions.emplace_back(std::move(state->m_current_function));
state->m_current_function = nullptr;
}
else
{
std::ostringstream ss;
ss << "Function with name \"" << state->m_current_menu->m_name << "\" already exists";
throw ParsingException(result.NextCapture(CAPTURE_TOKEN).GetPos(), ss.str());
}
}
else if(state->m_in_global_scope)
{
state->m_in_global_scope = false;
}
else
throw ParsingException(result.NextCapture(CAPTURE_TOKEN).GetPos(), "Invalid close block");
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "Parsing/Menu/MenuFileParser.h"
class SequenceCloseBlock final : public MenuFileParser::sequence_t
{
static constexpr auto CAPTURE_TOKEN = 1;
protected:
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override;
public:
SequenceCloseBlock();
};

View File

@ -0,0 +1,20 @@
#include "SequenceFunctionDef.h"
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
SequenceFunctionDef::SequenceFunctionDef()
{
const SimpleMatcherFactory create(this);
AddMatchers({
create.Keyword("functionDef"),
create.Char('{'),
});
}
void SequenceFunctionDef::ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const
{
assert(!state->m_current_menu);
state->m_current_item = std::make_unique<CommonItemDef>();
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "Parsing/Menu/MenuFileParser.h"
class SequenceFunctionDef final : public MenuFileParser::sequence_t
{
protected:
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override;
public:
SequenceFunctionDef();
};

View File

@ -0,0 +1,20 @@
#include "SequenceItemDef.h"
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
SequenceItemDef::SequenceItemDef()
{
const SimpleMatcherFactory create(this);
AddMatchers({
create.Keyword("itemDef"),
create.Char('{'),
});
}
void SequenceItemDef::ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const
{
assert(!state->m_current_menu);
state->m_current_item = std::make_unique<CommonItemDef>();
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "Parsing/Menu/MenuFileParser.h"
class SequenceItemDef final : public MenuFileParser::sequence_t
{
protected:
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override;
public:
SequenceItemDef();
};

View File

@ -0,0 +1,27 @@
#include "SequenceLoadMenu.h"
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
SequenceLoadMenu::SequenceLoadMenu()
{
const SimpleMatcherFactory create(this);
AddMatchers({
create.Keyword("loadMenu"),
create.Char('{'),
create.String().Capture(CAPTURE_MENU_NAME),
create.Char('}'),
});
}
void SequenceLoadMenu::ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const
{
assert(!state->m_current_menu);
const auto& menuNameToken = result.NextCapture(CAPTURE_MENU_NAME);
if (menuNameToken.StringValue().empty())
throw ParsingException(menuNameToken.GetPos(), "Invalid menu name");
state->m_menus_to_load.emplace_back(menuNameToken.StringValue());
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "Parsing/Menu/MenuFileParser.h"
class SequenceLoadMenu final : public MenuFileParser::sequence_t
{
static constexpr auto CAPTURE_MENU_NAME = 1;
protected:
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override;
public:
SequenceLoadMenu();
};

View File

@ -0,0 +1,20 @@
#include "SequenceMenuDef.h"
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
SequenceMenuDef::SequenceMenuDef()
{
const SimpleMatcherFactory create(this);
AddMatchers({
create.Keyword("menuDef"),
create.Char('{'),
});
}
void SequenceMenuDef::ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const
{
assert(!state->m_current_menu);
state->m_current_menu = std::make_unique<CommonMenuDef>();
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "Parsing/Menu/MenuFileParser.h"
class SequenceMenuDef final : public MenuFileParser::sequence_t
{
protected:
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override;
public:
SequenceMenuDef();
};

View File

@ -0,0 +1,18 @@
#include "SequenceOpenGlobalScopeBlock.h"
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
SequenceOpenGlobalScopeBlock::SequenceOpenGlobalScopeBlock()
{
const SimpleMatcherFactory create(this);
AddMatchers({
create.Char('{')
});
}
void SequenceOpenGlobalScopeBlock::ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const
{
assert(!state->m_in_global_scope);
state->m_in_global_scope = true;
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "Parsing/Menu/MenuFileParser.h"
class SequenceOpenGlobalScopeBlock final : public MenuFileParser::sequence_t
{
protected:
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override;
public:
SequenceOpenGlobalScopeBlock();
};