mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-10 14:58:10 -05: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:
@ -9,14 +9,14 @@
|
||||
|
||||
using namespace menu;
|
||||
|
||||
MenuFileParser::MenuFileParser(SimpleLexer* lexer, const FeatureLevel featureLevel)
|
||||
: AbstractParser(lexer, std::make_unique<MenuFileParserState>(featureLevel))
|
||||
MenuFileParser::MenuFileParser(SimpleLexer* lexer, const FeatureLevel featureLevel, bool permissiveMode)
|
||||
: AbstractParser(lexer, std::make_unique<MenuFileParserState>(featureLevel, permissiveMode))
|
||||
{
|
||||
CreateSequenceCollections();
|
||||
}
|
||||
|
||||
MenuFileParser::MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel, const MenuAssetZoneState* zoneState)
|
||||
: AbstractParser(lexer, std::make_unique<MenuFileParserState>(featureLevel, zoneState))
|
||||
MenuFileParser::MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel, bool permissiveMode, const MenuAssetZoneState* zoneState)
|
||||
: AbstractParser(lexer, std::make_unique<MenuFileParserState>(featureLevel, permissiveMode, zoneState))
|
||||
{
|
||||
CreateSequenceCollections();
|
||||
}
|
||||
@ -38,24 +38,25 @@ void MenuFileParser::CreateSequenceCollections()
|
||||
m_event_handler_set_scope_tests.clear();
|
||||
|
||||
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.AddSequences(featureLevel);
|
||||
noScopeSequences.AddSequences(featureLevel, permissive);
|
||||
|
||||
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);
|
||||
menuPropertySequences.AddSequences(featureLevel);
|
||||
menuPropertySequences.AddSequences(featureLevel, permissive);
|
||||
|
||||
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);
|
||||
functionPropertySequences.AddSequences(featureLevel);
|
||||
functionPropertySequences.AddSequences(featureLevel, permissive);
|
||||
|
||||
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()
|
||||
|
@ -26,8 +26,8 @@ namespace menu
|
||||
const std::vector<sequence_t*>& GetTestsForState() override;
|
||||
|
||||
public:
|
||||
MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel);
|
||||
MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel, const MenuAssetZoneState* zoneState);
|
||||
MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel, bool permissiveMode);
|
||||
MenuFileParser(SimpleLexer* lexer, FeatureLevel featureLevel, bool permissiveMode, const MenuAssetZoneState* zoneState);
|
||||
_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_permissive_mode(permissiveMode),
|
||||
m_in_global_scope(false),
|
||||
m_current_function(nullptr),
|
||||
m_current_menu(nullptr),
|
||||
m_current_item(nullptr),
|
||||
m_current_event_handler_set(nullptr),
|
||||
m_current_script_statement_terminated(true),
|
||||
m_current_nested_event_handler_set(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
MenuFileParserState::MenuFileParserState(const FeatureLevel featureLevel, const MenuAssetZoneState* zoneState)
|
||||
: MenuFileParserState(featureLevel)
|
||||
MenuFileParserState::MenuFileParserState(const FeatureLevel featureLevel, const bool permissiveMode, const MenuAssetZoneState* zoneState)
|
||||
: MenuFileParserState(featureLevel, permissiveMode)
|
||||
{
|
||||
for (const auto& function : zoneState->m_functions)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@ namespace menu
|
||||
};
|
||||
|
||||
const FeatureLevel m_feature_level;
|
||||
const bool m_permissive_mode;
|
||||
|
||||
std::vector<std::string> m_menus_to_load;
|
||||
std::vector<std::unique_ptr<CommonFunctionDef>> m_functions;
|
||||
@ -45,10 +46,11 @@ namespace menu
|
||||
CommonEventHandlerSet* m_current_event_handler_set;
|
||||
|
||||
std::ostringstream m_current_script;
|
||||
bool m_current_script_statement_terminated;
|
||||
std::stack<EventHandlerConditionState> m_condition_stack;
|
||||
CommonEventHandlerSet* m_current_nested_event_handler_set;
|
||||
|
||||
explicit MenuFileParserState(FeatureLevel featureLevel);
|
||||
MenuFileParserState(FeatureLevel featureLevel, const MenuAssetZoneState* zoneState);
|
||||
explicit MenuFileParserState(FeatureLevel featureLevel, bool permissiveMode);
|
||||
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_file_name(std::move(fileName)),
|
||||
m_stream(nullptr),
|
||||
m_zone_state(nullptr)
|
||||
m_zone_state(nullptr),
|
||||
m_permissive_mode(false)
|
||||
{
|
||||
OpenBaseStream(stream, std::move(includeCallback));
|
||||
SetupStreamProxies();
|
||||
@ -26,7 +27,8 @@ MenuFileReader::MenuFileReader(std::istream& stream, std::string fileName, const
|
||||
: m_feature_level(featureLevel),
|
||||
m_file_name(std::move(fileName)),
|
||||
m_stream(nullptr),
|
||||
m_zone_state(nullptr)
|
||||
m_zone_state(nullptr),
|
||||
m_permissive_mode(false)
|
||||
{
|
||||
OpenBaseStream(stream, nullptr);
|
||||
SetupStreamProxies();
|
||||
@ -117,6 +119,11 @@ void MenuFileReader::IncludeZoneState(const MenuAssetZoneState* zoneState)
|
||||
m_zone_state = zoneState;
|
||||
}
|
||||
|
||||
void MenuFileReader::SetPermissiveMode(const bool usePermissiveMode)
|
||||
{
|
||||
m_permissive_mode = usePermissiveMode;
|
||||
}
|
||||
|
||||
std::unique_ptr<ParsingResult> MenuFileReader::ReadMenuFile()
|
||||
{
|
||||
SimpleLexer::Config lexerConfig;
|
||||
@ -126,7 +133,7 @@ std::unique_ptr<ParsingResult> MenuFileReader::ReadMenuFile()
|
||||
MenuExpressionMatchers().ApplyTokensToLexerConfig(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())
|
||||
{
|
||||
|
@ -25,6 +25,7 @@ namespace menu
|
||||
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
|
||||
|
||||
const MenuAssetZoneState* m_zone_state;
|
||||
bool m_permissive_mode;
|
||||
|
||||
bool OpenBaseStream(std::istream& stream, include_callback_t includeCallback);
|
||||
void SetupDefinesProxy();
|
||||
@ -38,6 +39,7 @@ namespace menu
|
||||
MenuFileReader(std::istream& stream, std::string fileName, FeatureLevel featureLevel, include_callback_t includeCallback);
|
||||
|
||||
void IncludeZoneState(const MenuAssetZoneState* zoneState);
|
||||
void SetPermissiveMode(bool usePermissiveMode);
|
||||
|
||||
std::unique_ptr<ParsingResult> ReadMenuFile();
|
||||
};
|
||||
|
@ -22,8 +22,8 @@ namespace menu
|
||||
AbstractScopeSequenceHolder(const AbstractScopeSequenceHolder& other) = delete;
|
||||
AbstractScopeSequenceHolder(AbstractScopeSequenceHolder&& other) noexcept = default;
|
||||
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:
|
||||
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>());
|
||||
// If else and stuff
|
||||
@ -704,4 +757,9 @@ void EventHandlerSetScopeSequences::AddSequences(FeatureLevel featureLevel)
|
||||
AddSequence(std::make_unique<SequenceElseIf>());
|
||||
AddSequence(std::make_unique<SequenceElse>());
|
||||
AddSequence(std::make_unique<SequenceCloseBlock>());
|
||||
|
||||
if (permissive)
|
||||
{
|
||||
AddSequence(std::make_unique<SequenceSkipScriptToken>());
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,6 @@ namespace menu
|
||||
public:
|
||||
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<GenericStringPropertySequence>("name", [](const MenuFileParserState* state, const TokenPos&, const std::string& value)
|
||||
|
@ -9,6 +9,6 @@ namespace menu
|
||||
public:
|
||||
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<SequenceFunctionDef>());
|
||||
|
@ -9,6 +9,6 @@ namespace menu
|
||||
public:
|
||||
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<GenericStringPropertySequence>("name", [](const MenuFileParserState* state, const TokenPos&, const std::string& value)
|
||||
|
@ -9,6 +9,6 @@ namespace menu
|
||||
public:
|
||||
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<SequenceItemDef>());
|
||||
|
@ -9,6 +9,6 @@ namespace menu
|
||||
public:
|
||||
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>());
|
||||
}
|
||||
|
@ -9,6 +9,6 @@ namespace menu
|
||||
public:
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user