mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
Add permissive mode for menu parsing that accepts unknown script tokens as long as they can be put into the script
This commit is contained in:
parent
e94c48338c
commit
b082e471e7
@ -70,6 +70,12 @@ const CommandLineOption* const OPTION_LOAD =
|
|||||||
.Reusable()
|
.Reusable()
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
const CommandLineOption* const OPTION_MENU_PERMISSIVE =
|
||||||
|
CommandLineOption::Builder::Create()
|
||||||
|
.WithLongName("menu-permissive")
|
||||||
|
.WithDescription("Allows the usage of unknown script commands that can be compiled.")
|
||||||
|
.Build();
|
||||||
|
|
||||||
const CommandLineOption* const COMMAND_LINE_OPTIONS[]
|
const CommandLineOption* const COMMAND_LINE_OPTIONS[]
|
||||||
{
|
{
|
||||||
OPTION_HELP,
|
OPTION_HELP,
|
||||||
@ -79,7 +85,8 @@ const CommandLineOption* const COMMAND_LINE_OPTIONS[]
|
|||||||
OPTION_ASSET_SEARCH_PATH,
|
OPTION_ASSET_SEARCH_PATH,
|
||||||
OPTION_GDT_SEARCH_PATH,
|
OPTION_GDT_SEARCH_PATH,
|
||||||
OPTION_SOURCE_SEARCH_PATH,
|
OPTION_SOURCE_SEARCH_PATH,
|
||||||
OPTION_LOAD
|
OPTION_LOAD,
|
||||||
|
OPTION_MENU_PERMISSIVE
|
||||||
};
|
};
|
||||||
|
|
||||||
LinkerArgs::LinkerArgs()
|
LinkerArgs::LinkerArgs()
|
||||||
@ -257,6 +264,10 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv)
|
|||||||
if (m_argument_parser.IsOptionSpecified(OPTION_LOAD))
|
if (m_argument_parser.IsOptionSpecified(OPTION_LOAD))
|
||||||
m_zones_to_load = m_argument_parser.GetParametersForOption(OPTION_LOAD);
|
m_zones_to_load = m_argument_parser.GetParametersForOption(OPTION_LOAD);
|
||||||
|
|
||||||
|
// --menu-permissive
|
||||||
|
if (m_argument_parser.IsOptionSpecified(OPTION_MENU_PERMISSIVE))
|
||||||
|
ObjLoading::Configuration.PermissiveMenuParsing = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "ObjLoading.h"
|
||||||
#include "Game/IW4/IW4.h"
|
#include "Game/IW4/IW4.h"
|
||||||
#include "Parsing/Menu/MenuFileReader.h"
|
#include "Parsing/Menu/MenuFileReader.h"
|
||||||
#include "Pool/GlobalAssetPool.h"
|
#include "Pool/GlobalAssetPool.h"
|
||||||
@ -101,6 +102,7 @@ bool AssetLoaderMenuList::LoadFromRaw(const std::string& assetName, ISearchPath*
|
|||||||
});
|
});
|
||||||
|
|
||||||
reader.IncludeZoneState(zoneState);
|
reader.IncludeZoneState(zoneState);
|
||||||
|
reader.SetPermissiveMode(ObjLoading::Configuration.PermissiveMenuParsing);
|
||||||
|
|
||||||
const auto menuFileResult = reader.ReadMenuFile();
|
const auto menuFileResult = reader.ReadMenuFile();
|
||||||
if (menuFileResult)
|
if (menuFileResult)
|
||||||
|
@ -12,6 +12,7 @@ public:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool Verbose = false;
|
bool Verbose = false;
|
||||||
|
bool PermissiveMenuParsing = false;
|
||||||
} Configuration;
|
} Configuration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
|
|
||||||
using namespace menu;
|
using namespace menu;
|
||||||
|
|
||||||
MenuFileParser::MenuFileParser(SimpleLexer* lexer, const FeatureLevel featureLevel)
|
MenuFileParser::MenuFileParser(SimpleLexer* lexer, const FeatureLevel featureLevel, bool permissiveMode)
|
||||||
: AbstractParser(lexer, std::make_unique<MenuFileParserState>(featureLevel))
|
: AbstractParser(lexer, std::make_unique<MenuFileParserState>(featureLevel, permissiveMode))
|
||||||
{
|
{
|
||||||
CreateSequenceCollections();
|
CreateSequenceCollections();
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuFileParser::MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel, const MenuAssetZoneState* zoneState)
|
MenuFileParser::MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel, bool permissiveMode, const MenuAssetZoneState* zoneState)
|
||||||
: AbstractParser(lexer, std::make_unique<MenuFileParserState>(featureLevel, zoneState))
|
: AbstractParser(lexer, std::make_unique<MenuFileParserState>(featureLevel, permissiveMode, zoneState))
|
||||||
{
|
{
|
||||||
CreateSequenceCollections();
|
CreateSequenceCollections();
|
||||||
}
|
}
|
||||||
@ -38,24 +38,25 @@ void MenuFileParser::CreateSequenceCollections()
|
|||||||
m_event_handler_set_scope_tests.clear();
|
m_event_handler_set_scope_tests.clear();
|
||||||
|
|
||||||
const auto featureLevel = m_state->m_feature_level;
|
const auto featureLevel = m_state->m_feature_level;
|
||||||
|
const auto permissive = m_state->m_permissive_mode;
|
||||||
|
|
||||||
NoScopeSequences noScopeSequences(m_all_tests, m_no_scope_tests);
|
NoScopeSequences noScopeSequences(m_all_tests, m_no_scope_tests);
|
||||||
noScopeSequences.AddSequences(featureLevel);
|
noScopeSequences.AddSequences(featureLevel, permissive);
|
||||||
|
|
||||||
GlobalScopeSequences globalScopeSequences(m_all_tests, m_global_scope_tests);
|
GlobalScopeSequences globalScopeSequences(m_all_tests, m_global_scope_tests);
|
||||||
globalScopeSequences.AddSequences(featureLevel);
|
globalScopeSequences.AddSequences(featureLevel, permissive);
|
||||||
|
|
||||||
MenuScopeSequences menuPropertySequences(m_all_tests, m_menu_scope_tests);
|
MenuScopeSequences menuPropertySequences(m_all_tests, m_menu_scope_tests);
|
||||||
menuPropertySequences.AddSequences(featureLevel);
|
menuPropertySequences.AddSequences(featureLevel, permissive);
|
||||||
|
|
||||||
ItemScopeSequences itemPropertySequences(m_all_tests, m_item_scope_tests);
|
ItemScopeSequences itemPropertySequences(m_all_tests, m_item_scope_tests);
|
||||||
itemPropertySequences.AddSequences(featureLevel);
|
itemPropertySequences.AddSequences(featureLevel, permissive);
|
||||||
|
|
||||||
FunctionScopeSequences functionPropertySequences(m_all_tests, m_function_scope_tests);
|
FunctionScopeSequences functionPropertySequences(m_all_tests, m_function_scope_tests);
|
||||||
functionPropertySequences.AddSequences(featureLevel);
|
functionPropertySequences.AddSequences(featureLevel, permissive);
|
||||||
|
|
||||||
EventHandlerSetScopeSequences eventHandlerSetScopeSequences(m_all_tests, m_event_handler_set_scope_tests);
|
EventHandlerSetScopeSequences eventHandlerSetScopeSequences(m_all_tests, m_event_handler_set_scope_tests);
|
||||||
eventHandlerSetScopeSequences.AddSequences(featureLevel);
|
eventHandlerSetScopeSequences.AddSequences(featureLevel, permissive);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<MenuFileParser::sequence_t*>& MenuFileParser::GetTestsForState()
|
const std::vector<MenuFileParser::sequence_t*>& MenuFileParser::GetTestsForState()
|
||||||
|
@ -26,8 +26,8 @@ namespace menu
|
|||||||
const std::vector<sequence_t*>& GetTestsForState() override;
|
const std::vector<sequence_t*>& GetTestsForState() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel);
|
MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel, bool permissiveMode);
|
||||||
MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel, const MenuAssetZoneState* zoneState);
|
MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel, bool permissiveMode, const MenuAssetZoneState* zoneState);
|
||||||
_NODISCARD MenuFileParserState* GetState() const;
|
_NODISCARD MenuFileParserState* GetState() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -14,19 +14,21 @@ MenuFileParserState::EventHandlerConditionState::EventHandlerConditionState(Comm
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuFileParserState::MenuFileParserState(const FeatureLevel featureLevel)
|
MenuFileParserState::MenuFileParserState(const FeatureLevel featureLevel, const bool permissiveMode)
|
||||||
: m_feature_level(featureLevel),
|
: m_feature_level(featureLevel),
|
||||||
|
m_permissive_mode(permissiveMode),
|
||||||
m_in_global_scope(false),
|
m_in_global_scope(false),
|
||||||
m_current_function(nullptr),
|
m_current_function(nullptr),
|
||||||
m_current_menu(nullptr),
|
m_current_menu(nullptr),
|
||||||
m_current_item(nullptr),
|
m_current_item(nullptr),
|
||||||
m_current_event_handler_set(nullptr),
|
m_current_event_handler_set(nullptr),
|
||||||
|
m_current_script_statement_terminated(true),
|
||||||
m_current_nested_event_handler_set(nullptr)
|
m_current_nested_event_handler_set(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuFileParserState::MenuFileParserState(const FeatureLevel featureLevel, const MenuAssetZoneState* zoneState)
|
MenuFileParserState::MenuFileParserState(const FeatureLevel featureLevel, const bool permissiveMode, const MenuAssetZoneState* zoneState)
|
||||||
: MenuFileParserState(featureLevel)
|
: MenuFileParserState(featureLevel, permissiveMode)
|
||||||
{
|
{
|
||||||
for (const auto& function : zoneState->m_functions)
|
for (const auto& function : zoneState->m_functions)
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,7 @@ namespace menu
|
|||||||
};
|
};
|
||||||
|
|
||||||
const FeatureLevel m_feature_level;
|
const FeatureLevel m_feature_level;
|
||||||
|
const bool m_permissive_mode;
|
||||||
|
|
||||||
std::vector<std::string> m_menus_to_load;
|
std::vector<std::string> m_menus_to_load;
|
||||||
std::vector<std::unique_ptr<CommonFunctionDef>> m_functions;
|
std::vector<std::unique_ptr<CommonFunctionDef>> m_functions;
|
||||||
@ -45,10 +46,11 @@ namespace menu
|
|||||||
CommonEventHandlerSet* m_current_event_handler_set;
|
CommonEventHandlerSet* m_current_event_handler_set;
|
||||||
|
|
||||||
std::ostringstream m_current_script;
|
std::ostringstream m_current_script;
|
||||||
|
bool m_current_script_statement_terminated;
|
||||||
std::stack<EventHandlerConditionState> m_condition_stack;
|
std::stack<EventHandlerConditionState> m_condition_stack;
|
||||||
CommonEventHandlerSet* m_current_nested_event_handler_set;
|
CommonEventHandlerSet* m_current_nested_event_handler_set;
|
||||||
|
|
||||||
explicit MenuFileParserState(FeatureLevel featureLevel);
|
explicit MenuFileParserState(FeatureLevel featureLevel, bool permissiveMode);
|
||||||
MenuFileParserState(FeatureLevel featureLevel, const MenuAssetZoneState* zoneState);
|
MenuFileParserState(FeatureLevel featureLevel, bool permissiveMode, const MenuAssetZoneState* zoneState);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@ MenuFileReader::MenuFileReader(std::istream& stream, std::string fileName, const
|
|||||||
: m_feature_level(featureLevel),
|
: m_feature_level(featureLevel),
|
||||||
m_file_name(std::move(fileName)),
|
m_file_name(std::move(fileName)),
|
||||||
m_stream(nullptr),
|
m_stream(nullptr),
|
||||||
m_zone_state(nullptr)
|
m_zone_state(nullptr),
|
||||||
|
m_permissive_mode(false)
|
||||||
{
|
{
|
||||||
OpenBaseStream(stream, std::move(includeCallback));
|
OpenBaseStream(stream, std::move(includeCallback));
|
||||||
SetupStreamProxies();
|
SetupStreamProxies();
|
||||||
@ -26,7 +27,8 @@ MenuFileReader::MenuFileReader(std::istream& stream, std::string fileName, const
|
|||||||
: m_feature_level(featureLevel),
|
: m_feature_level(featureLevel),
|
||||||
m_file_name(std::move(fileName)),
|
m_file_name(std::move(fileName)),
|
||||||
m_stream(nullptr),
|
m_stream(nullptr),
|
||||||
m_zone_state(nullptr)
|
m_zone_state(nullptr),
|
||||||
|
m_permissive_mode(false)
|
||||||
{
|
{
|
||||||
OpenBaseStream(stream, nullptr);
|
OpenBaseStream(stream, nullptr);
|
||||||
SetupStreamProxies();
|
SetupStreamProxies();
|
||||||
@ -117,6 +119,11 @@ void MenuFileReader::IncludeZoneState(const MenuAssetZoneState* zoneState)
|
|||||||
m_zone_state = zoneState;
|
m_zone_state = zoneState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MenuFileReader::SetPermissiveMode(const bool usePermissiveMode)
|
||||||
|
{
|
||||||
|
m_permissive_mode = usePermissiveMode;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<ParsingResult> MenuFileReader::ReadMenuFile()
|
std::unique_ptr<ParsingResult> MenuFileReader::ReadMenuFile()
|
||||||
{
|
{
|
||||||
SimpleLexer::Config lexerConfig;
|
SimpleLexer::Config lexerConfig;
|
||||||
@ -126,7 +133,7 @@ std::unique_ptr<ParsingResult> MenuFileReader::ReadMenuFile()
|
|||||||
MenuExpressionMatchers().ApplyTokensToLexerConfig(lexerConfig);
|
MenuExpressionMatchers().ApplyTokensToLexerConfig(lexerConfig);
|
||||||
|
|
||||||
const auto lexer = std::make_unique<SimpleLexer>(m_stream, std::move(lexerConfig));
|
const auto lexer = std::make_unique<SimpleLexer>(m_stream, std::move(lexerConfig));
|
||||||
const auto parser = std::make_unique<MenuFileParser>(lexer.get(), m_feature_level);
|
const auto parser = std::make_unique<MenuFileParser>(lexer.get(), m_feature_level, m_permissive_mode, m_zone_state);
|
||||||
|
|
||||||
if (!parser->Parse())
|
if (!parser->Parse())
|
||||||
{
|
{
|
||||||
|
@ -25,6 +25,7 @@ namespace menu
|
|||||||
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
|
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
|
||||||
|
|
||||||
const MenuAssetZoneState* m_zone_state;
|
const MenuAssetZoneState* m_zone_state;
|
||||||
|
bool m_permissive_mode;
|
||||||
|
|
||||||
bool OpenBaseStream(std::istream& stream, include_callback_t includeCallback);
|
bool OpenBaseStream(std::istream& stream, include_callback_t includeCallback);
|
||||||
void SetupDefinesProxy();
|
void SetupDefinesProxy();
|
||||||
@ -38,6 +39,7 @@ namespace menu
|
|||||||
MenuFileReader(std::istream& stream, std::string fileName, FeatureLevel featureLevel, include_callback_t includeCallback);
|
MenuFileReader(std::istream& stream, std::string fileName, FeatureLevel featureLevel, include_callback_t includeCallback);
|
||||||
|
|
||||||
void IncludeZoneState(const MenuAssetZoneState* zoneState);
|
void IncludeZoneState(const MenuAssetZoneState* zoneState);
|
||||||
|
void SetPermissiveMode(bool usePermissiveMode);
|
||||||
|
|
||||||
std::unique_ptr<ParsingResult> ReadMenuFile();
|
std::unique_ptr<ParsingResult> ReadMenuFile();
|
||||||
};
|
};
|
||||||
|
@ -22,8 +22,8 @@ namespace menu
|
|||||||
AbstractScopeSequenceHolder(const AbstractScopeSequenceHolder& other) = delete;
|
AbstractScopeSequenceHolder(const AbstractScopeSequenceHolder& other) = delete;
|
||||||
AbstractScopeSequenceHolder(AbstractScopeSequenceHolder&& other) noexcept = default;
|
AbstractScopeSequenceHolder(AbstractScopeSequenceHolder&& other) noexcept = default;
|
||||||
AbstractScopeSequenceHolder& operator=(const AbstractScopeSequenceHolder& other) = delete;
|
AbstractScopeSequenceHolder& operator=(const AbstractScopeSequenceHolder& other) = delete;
|
||||||
AbstractScopeSequenceHolder& operator=(AbstractScopeSequenceHolder&& other) noexcept = default;
|
AbstractScopeSequenceHolder& operator=(AbstractScopeSequenceHolder&& other) noexcept = delete;
|
||||||
|
|
||||||
virtual void AddSequences(FeatureLevel featureLevel) = 0;
|
virtual void AddSequences(FeatureLevel featureLevel, bool permissive) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -195,6 +195,59 @@ namespace menu::event_handler_set_scope_sequences
|
|||||||
protected:
|
protected:
|
||||||
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||||
{
|
{
|
||||||
|
if (!state->m_current_script_statement_terminated)
|
||||||
|
{
|
||||||
|
state->m_current_script << "; ";
|
||||||
|
state->m_current_script_statement_terminated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SequenceSkipScriptToken final : public MenuFileParser::sequence_t
|
||||||
|
{
|
||||||
|
static constexpr auto CAPTURE_SCRIPT_TOKEN = 1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SequenceSkipScriptToken()
|
||||||
|
{
|
||||||
|
const ScriptMatcherFactory create(this);
|
||||||
|
|
||||||
|
AddMatchers({
|
||||||
|
create.Or({
|
||||||
|
create.Text(),
|
||||||
|
create.Numeric()
|
||||||
|
}).Capture(CAPTURE_SCRIPT_TOKEN)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||||
|
{
|
||||||
|
const auto& capture = result.NextCapture(CAPTURE_SCRIPT_TOKEN);
|
||||||
|
|
||||||
|
switch(capture.m_type)
|
||||||
|
{
|
||||||
|
case SimpleParserValueType::STRING:
|
||||||
|
state->m_current_script << "\"" << capture.StringValue() << "\" ";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SimpleParserValueType::IDENTIFIER:
|
||||||
|
state->m_current_script << "\"" << capture.IdentifierValue() << "\" ";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SimpleParserValueType::INTEGER:
|
||||||
|
state->m_current_script << "\"" << capture.IntegerValue() << "\" ";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SimpleParserValueType::FLOATING_POINT:
|
||||||
|
state->m_current_script << "\"" << capture.FloatingPointValue() << "\" ";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw ParsingException(capture.GetPos(), "Invalid script token type for skipping");
|
||||||
|
}
|
||||||
|
|
||||||
|
state->m_current_script_statement_terminated = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -611,7 +664,7 @@ EventHandlerSetScopeSequences::EventHandlerSetScopeSequences(std::vector<std::un
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerSetScopeSequences::AddSequences(FeatureLevel featureLevel)
|
void EventHandlerSetScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive)
|
||||||
{
|
{
|
||||||
AddSequence(std::make_unique<SequenceSkipEmptyStatements>());
|
AddSequence(std::make_unique<SequenceSkipEmptyStatements>());
|
||||||
// If else and stuff
|
// If else and stuff
|
||||||
@ -704,4 +757,9 @@ void EventHandlerSetScopeSequences::AddSequences(FeatureLevel featureLevel)
|
|||||||
AddSequence(std::make_unique<SequenceElseIf>());
|
AddSequence(std::make_unique<SequenceElseIf>());
|
||||||
AddSequence(std::make_unique<SequenceElse>());
|
AddSequence(std::make_unique<SequenceElse>());
|
||||||
AddSequence(std::make_unique<SequenceCloseBlock>());
|
AddSequence(std::make_unique<SequenceCloseBlock>());
|
||||||
|
|
||||||
|
if (permissive)
|
||||||
|
{
|
||||||
|
AddSequence(std::make_unique<SequenceSkipScriptToken>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,6 @@ namespace menu
|
|||||||
public:
|
public:
|
||||||
EventHandlerSetScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
EventHandlerSetScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
||||||
|
|
||||||
void AddSequences(FeatureLevel featureLevel) override;
|
void AddSequences(FeatureLevel featureLevel, bool permissive) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ FunctionScopeSequences::FunctionScopeSequences(std::vector<std::unique_ptr<MenuF
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionScopeSequences::AddSequences(FeatureLevel featureLevel)
|
void FunctionScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive)
|
||||||
{
|
{
|
||||||
AddSequence(std::make_unique<SequenceCloseBlock>());
|
AddSequence(std::make_unique<SequenceCloseBlock>());
|
||||||
AddSequence(std::make_unique<GenericStringPropertySequence>("name", [](const MenuFileParserState* state, const TokenPos&, const std::string& value)
|
AddSequence(std::make_unique<GenericStringPropertySequence>("name", [](const MenuFileParserState* state, const TokenPos&, const std::string& value)
|
||||||
|
@ -9,6 +9,6 @@ namespace menu
|
|||||||
public:
|
public:
|
||||||
FunctionScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
FunctionScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
||||||
|
|
||||||
void AddSequences(FeatureLevel featureLevel) override;
|
void AddSequences(FeatureLevel featureLevel, bool permissive) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ GlobalScopeSequences::GlobalScopeSequences(std::vector<std::unique_ptr<MenuFileP
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalScopeSequences::AddSequences(FeatureLevel featureLevel)
|
void GlobalScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive)
|
||||||
{
|
{
|
||||||
AddSequence(std::make_unique<SequenceCloseBlock>());
|
AddSequence(std::make_unique<SequenceCloseBlock>());
|
||||||
AddSequence(std::make_unique<SequenceFunctionDef>());
|
AddSequence(std::make_unique<SequenceFunctionDef>());
|
||||||
|
@ -9,6 +9,6 @@ namespace menu
|
|||||||
public:
|
public:
|
||||||
GlobalScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
GlobalScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
||||||
|
|
||||||
void AddSequences(FeatureLevel featureLevel) override;
|
void AddSequences(FeatureLevel featureLevel, bool permissive) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,7 @@ ItemScopeSequences::ItemScopeSequences(std::vector<std::unique_ptr<MenuFileParse
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemScopeSequences::AddSequences(FeatureLevel featureLevel)
|
void ItemScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive)
|
||||||
{
|
{
|
||||||
AddSequence(std::make_unique<SequenceCloseBlock>());
|
AddSequence(std::make_unique<SequenceCloseBlock>());
|
||||||
AddSequence(std::make_unique<GenericStringPropertySequence>("name", [](const MenuFileParserState* state, const TokenPos&, const std::string& value)
|
AddSequence(std::make_unique<GenericStringPropertySequence>("name", [](const MenuFileParserState* state, const TokenPos&, const std::string& value)
|
||||||
|
@ -9,6 +9,6 @@ namespace menu
|
|||||||
public:
|
public:
|
||||||
ItemScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
ItemScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
||||||
|
|
||||||
void AddSequences(FeatureLevel featureLevel) override;
|
void AddSequences(FeatureLevel featureLevel, bool permissive) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ MenuScopeSequences::MenuScopeSequences(std::vector<std::unique_ptr<MenuFileParse
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuScopeSequences::AddSequences(FeatureLevel featureLevel)
|
void MenuScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive)
|
||||||
{
|
{
|
||||||
AddSequence(std::make_unique<SequenceCloseBlock>());
|
AddSequence(std::make_unique<SequenceCloseBlock>());
|
||||||
AddSequence(std::make_unique<SequenceItemDef>());
|
AddSequence(std::make_unique<SequenceItemDef>());
|
||||||
|
@ -9,6 +9,6 @@ namespace menu
|
|||||||
public:
|
public:
|
||||||
MenuScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
MenuScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
||||||
|
|
||||||
void AddSequences(FeatureLevel featureLevel) override;
|
void AddSequences(FeatureLevel featureLevel, bool permissive) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ NoScopeSequences::NoScopeSequences(std::vector<std::unique_ptr<MenuFileParser::s
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoScopeSequences::AddSequences(FeatureLevel featureLevel)
|
void NoScopeSequences::AddSequences(FeatureLevel featureLevel, bool permissive)
|
||||||
{
|
{
|
||||||
AddSequence(std::make_unique<SequenceOpenGlobalScope>());
|
AddSequence(std::make_unique<SequenceOpenGlobalScope>());
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,6 @@ namespace menu
|
|||||||
public:
|
public:
|
||||||
NoScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
NoScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
|
||||||
|
|
||||||
void AddSequences(FeatureLevel featureLevel) override;
|
void AddSequences(FeatureLevel featureLevel, bool permissive) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,13 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
unsigned m_consumed_token_count;
|
unsigned m_consumed_token_count;
|
||||||
|
|
||||||
explicit EventHandlerSetSequenceTestsHelper(FeatureLevel featureLevel)
|
explicit EventHandlerSetSequenceTestsHelper(FeatureLevel featureLevel, bool permissive)
|
||||||
: m_state(std::make_unique<MenuFileParserState>(featureLevel)),
|
: m_state(std::make_unique<MenuFileParserState>(featureLevel, false)),
|
||||||
m_event_handler_set(std::make_unique<CommonEventHandlerSet>()),
|
m_event_handler_set(std::make_unique<CommonEventHandlerSet>()),
|
||||||
m_consumed_token_count(0u)
|
m_consumed_token_count(0u)
|
||||||
{
|
{
|
||||||
EventHandlerSetScopeSequences scopeSequences(m_all_sequences, m_scope_sequences);
|
EventHandlerSetScopeSequences scopeSequences(m_all_sequences, m_scope_sequences);
|
||||||
scopeSequences.AddSequences(m_state->m_feature_level);
|
scopeSequences.AddSequences(m_state->m_feature_level, permissive);
|
||||||
|
|
||||||
m_state->m_current_menu = m_state->m_menus.emplace_back(std::make_unique<CommonMenuDef>()).get();
|
m_state->m_current_menu = m_state->m_menus.emplace_back(std::make_unique<CommonMenuDef>()).get();
|
||||||
m_state->m_current_event_handler_set = m_event_handler_set.get();
|
m_state->m_current_event_handler_set = m_event_handler_set.get();
|
||||||
@ -54,8 +54,11 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
{
|
{
|
||||||
const auto couldMatch = sequence->MatchSequence(m_lexer.get(), m_state.get(), m_consumed_token_count);
|
const auto couldMatch = sequence->MatchSequence(m_lexer.get(), m_state.get(), m_consumed_token_count);
|
||||||
if (couldMatch)
|
if (couldMatch)
|
||||||
|
{
|
||||||
|
m_lexer->PopTokens(static_cast<int>(m_consumed_token_count));
|
||||||
return couldMatch;
|
return couldMatch;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -64,7 +67,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
#pragma region General
|
#pragma region General
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Keyword casing doesnt matter", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Keyword casing doesnt matter", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Identifier(pos, new std::string("fadein")),
|
SimpleParserValue::Identifier(pos, new std::string("fadein")),
|
||||||
@ -84,7 +87,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Invalid keywords are not recognized", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Invalid keywords are not recognized", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Identifier(pos, new std::string("noScriptCommand")),
|
SimpleParserValue::Identifier(pos, new std::string("noScriptCommand")),
|
||||||
@ -99,6 +102,43 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
REQUIRE(helper.m_consumed_token_count == 0);
|
REQUIRE(helper.m_consumed_token_count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("EventHandlerSetScopeSequences: Permissive mode ignores unknown script tokens and adds them to script", "[parsing][sequence][menu]")
|
||||||
|
{
|
||||||
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, true);
|
||||||
|
const TokenPos pos;
|
||||||
|
helper.Tokens({
|
||||||
|
SimpleParserValue::Identifier(pos, new std::string("uiScript")),
|
||||||
|
SimpleParserValue::Identifier(pos, new std::string("somethingUnknown")),
|
||||||
|
SimpleParserValue::String(pos, new std::string("anArgumentForTheUnknownScript")),
|
||||||
|
SimpleParserValue::Character(pos, ';'),
|
||||||
|
SimpleParserValue::EndOfFile(pos)
|
||||||
|
});
|
||||||
|
|
||||||
|
auto result = helper.PerformTest();
|
||||||
|
REQUIRE(result);
|
||||||
|
REQUIRE(helper.m_consumed_token_count == 1);
|
||||||
|
auto script = helper.m_state->m_current_script.str();
|
||||||
|
REQUIRE(script == R"("uiScript" )");
|
||||||
|
|
||||||
|
result = helper.PerformTest();
|
||||||
|
REQUIRE(result);
|
||||||
|
REQUIRE(helper.m_consumed_token_count == 1);
|
||||||
|
script = helper.m_state->m_current_script.str();
|
||||||
|
REQUIRE(script == R"("uiScript" "somethingUnknown" )");
|
||||||
|
|
||||||
|
result = helper.PerformTest();
|
||||||
|
REQUIRE(result);
|
||||||
|
REQUIRE(helper.m_consumed_token_count == 1);
|
||||||
|
script = helper.m_state->m_current_script.str();
|
||||||
|
REQUIRE(script == R"("uiScript" "somethingUnknown" "anArgumentForTheUnknownScript" )");
|
||||||
|
|
||||||
|
result = helper.PerformTest();
|
||||||
|
REQUIRE(result);
|
||||||
|
REQUIRE(helper.m_consumed_token_count == 1);
|
||||||
|
script = helper.m_state->m_current_script.str();
|
||||||
|
REQUIRE(script == R"("uiScript" "somethingUnknown" "anArgumentForTheUnknownScript" ; )");
|
||||||
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
void TestGenericScriptStatement(const std::initializer_list<Movable<SimpleParserValue>> tokens, const std::string& expectedScript)
|
void TestGenericScriptStatement(const std::initializer_list<Movable<SimpleParserValue>> tokens, const std::string& expectedScript)
|
||||||
@ -109,7 +149,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
tokenList.emplace_back(SimpleParserValue::Character(TokenPos(), ';'));
|
tokenList.emplace_back(SimpleParserValue::Character(TokenPos(), ';'));
|
||||||
tokenList.emplace_back(SimpleParserValue::EndOfFile(TokenPos()));
|
tokenList.emplace_back(SimpleParserValue::EndOfFile(TokenPos()));
|
||||||
|
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
helper.Tokens(std::move(tokenList));
|
helper.Tokens(std::move(tokenList));
|
||||||
|
|
||||||
const auto result = helper.PerformTest();
|
const auto result = helper.PerformTest();
|
||||||
@ -220,7 +260,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Ensure cannot use setColor with no color", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Ensure cannot use setColor with no color", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Identifier(pos, new std::string("setColor")),
|
SimpleParserValue::Identifier(pos, new std::string("setColor")),
|
||||||
@ -761,7 +801,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Ensure setLocalVarBool is setLocalVar handler on non-static value", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Ensure setLocalVarBool is setLocalVar handler on non-static value", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Identifier(TokenPos(), new std::string("setLocalVarBool")),
|
SimpleParserValue::Identifier(TokenPos(), new std::string("setLocalVarBool")),
|
||||||
@ -796,7 +836,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Ensure setLocalVarInt is setLocalVar handler on non-static value", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Ensure setLocalVarInt is setLocalVar handler on non-static value", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Identifier(TokenPos(), new std::string("setLocalVarInt")),
|
SimpleParserValue::Identifier(TokenPos(), new std::string("setLocalVarInt")),
|
||||||
@ -831,7 +871,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Ensure setLocalVarFloat is setLocalVar handler on non-static value", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Ensure setLocalVarFloat is setLocalVar handler on non-static value", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Identifier(TokenPos(), new std::string("setLocalVarFloat")),
|
SimpleParserValue::Identifier(TokenPos(), new std::string("setLocalVarFloat")),
|
||||||
@ -866,7 +906,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Ensure setLocalVarString is setLocalVar handler on non-static value", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Ensure setLocalVarString is setLocalVar handler on non-static value", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Identifier(TokenPos(), new std::string("setLocalVarString")),
|
SimpleParserValue::Identifier(TokenPos(), new std::string("setLocalVarString")),
|
||||||
@ -905,7 +945,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Closing block terminates EventHandlerSet", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Closing block terminates EventHandlerSet", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -926,7 +966,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Closing block finishes current script", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Closing block finishes current script", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -955,7 +995,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: If opens new condition", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: If opens new condition", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Identifier(pos, new std::string("if")),
|
SimpleParserValue::Identifier(pos, new std::string("if")),
|
||||||
@ -1001,7 +1041,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: If applies current script", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: If applies current script", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Identifier(pos, new std::string("if")),
|
SimpleParserValue::Identifier(pos, new std::string("if")),
|
||||||
@ -1040,7 +1080,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: ElseIf opens new condition", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: ElseIf opens new condition", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1094,7 +1134,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: ElseIf applies current script", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: ElseIf applies current script", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1138,7 +1178,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: ElseIf cannot be specified when not in if", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: ElseIf cannot be specified when not in if", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1155,7 +1195,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: ElseIf cannot be specified when else was already used", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: ElseIf cannot be specified when else was already used", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1177,7 +1217,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Else switches to else element", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Else switches to else element", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1209,7 +1249,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Else keeps auto_skip value", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Else keeps auto_skip value", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1241,7 +1281,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Else cannot be specified when not in if", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Else cannot be specified when not in if", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1255,7 +1295,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: Else cannot be specified when else was already used", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: Else cannot be specified when else was already used", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1274,7 +1314,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: CloseBlock closes if statements", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: CloseBlock closes if statements", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1299,7 +1339,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: CloseBlock closes nested if statements to parent if statement", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: CloseBlock closes nested if statements to parent if statement", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1328,7 +1368,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: CloseBlock closes nested if statements to parent else statement", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: CloseBlock closes nested if statements to parent else statement", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1358,7 +1398,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: CloseBlock closes all autoskip conditions to parent if statement", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: CloseBlock closes all autoskip conditions to parent if statement", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
@ -1391,7 +1431,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
|
|
||||||
TEST_CASE("EventHandlerSetScopeSequences: CloseBlock closes all autoskip conditions to base", "[parsing][sequence][menu]")
|
TEST_CASE("EventHandlerSetScopeSequences: CloseBlock closes all autoskip conditions to base", "[parsing][sequence][menu]")
|
||||||
{
|
{
|
||||||
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4);
|
EventHandlerSetSequenceTestsHelper helper(FeatureLevel::IW4, false);
|
||||||
const TokenPos pos;
|
const TokenPos pos;
|
||||||
helper.Tokens({
|
helper.Tokens({
|
||||||
SimpleParserValue::Character(pos, '}'),
|
SimpleParserValue::Character(pos, '}'),
|
||||||
|
@ -14,20 +14,20 @@ class MockLexer final : public ILexer<TokenType>
|
|||||||
|
|
||||||
std::vector<TokenType> m_tokens;
|
std::vector<TokenType> m_tokens;
|
||||||
TokenType m_eof;
|
TokenType m_eof;
|
||||||
int m_pop_count;
|
size_t m_pop_count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MockLexer(std::initializer_list<Movable<TokenType>> tokens, TokenType eof)
|
MockLexer(std::initializer_list<Movable<TokenType>> tokens, TokenType eof)
|
||||||
: m_tokens(std::make_move_iterator(tokens.begin()), std::make_move_iterator(tokens.end())),
|
: m_tokens(std::make_move_iterator(tokens.begin()), std::make_move_iterator(tokens.end())),
|
||||||
m_eof(std::move(eof)),
|
m_eof(std::move(eof)),
|
||||||
m_pop_count(0)
|
m_pop_count(0u)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MockLexer(std::vector<TokenType> tokens, TokenType eof)
|
MockLexer(std::vector<TokenType> tokens, TokenType eof)
|
||||||
: m_tokens(std::move(tokens)),
|
: m_tokens(std::move(tokens)),
|
||||||
m_eof(std::move(eof)),
|
m_eof(std::move(eof)),
|
||||||
m_pop_count(0)
|
m_pop_count(0u)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,28 +39,30 @@ public:
|
|||||||
|
|
||||||
const TokenType& GetToken(const unsigned index) override
|
const TokenType& GetToken(const unsigned index) override
|
||||||
{
|
{
|
||||||
if (index < m_tokens.size())
|
const auto absoluteIndex = m_pop_count + index;
|
||||||
return m_tokens[index];
|
if (absoluteIndex < m_tokens.size())
|
||||||
|
return m_tokens[absoluteIndex];
|
||||||
|
|
||||||
return m_eof;
|
return m_eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopTokens(const int amount) override
|
void PopTokens(const int amount) override
|
||||||
{
|
{
|
||||||
m_pop_count += amount;
|
assert(amount >= 0);
|
||||||
|
m_pop_count += static_cast<size_t>(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsEof() override
|
bool IsEof() override
|
||||||
{
|
{
|
||||||
return !m_tokens.empty();
|
return !m_tokens.empty() || m_pop_count >= m_tokens.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const TokenPos& GetPos() override
|
const TokenPos& GetPos() override
|
||||||
{
|
{
|
||||||
return !m_tokens.empty() ? m_tokens[0].GetPos() : m_eof.GetPos();
|
return !m_tokens.empty() && m_pop_count < m_tokens.size() ? m_tokens[m_pop_count].GetPos() : m_eof.GetPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
_NODISCARD int GetPopCount() const
|
_NODISCARD size_t GetPopCount() const
|
||||||
{
|
{
|
||||||
return m_pop_count;
|
return m_pop_count;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user