diff options
author | Spartan322 <Megacake1234@gmail.com> | 2023-08-23 20:21:14 +0200 |
---|---|---|
committer | Spartan322 <Megacake1234@gmail.com> | 2023-08-23 20:21:14 +0200 |
commit | 9d530253ee944228d5d19e6ae41d93e3e2b8cfbc (patch) | |
tree | 0ced0fed95dc1b21cf9a6b8b10b66843c65ac0b9 /src/openvic-dataloader | |
parent | dabf33050b6287fa7217858cb6021e1105f96894 (diff) |
Add decision_parse to Parser
Diffstat (limited to 'src/openvic-dataloader')
-rw-r--r-- | src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp | 31 | ||||
-rw-r--r-- | src/openvic-dataloader/v2script/DecisionGrammar.hpp | 100 | ||||
-rw-r--r-- | src/openvic-dataloader/v2script/EventGrammar.hpp | 28 | ||||
-rw-r--r-- | src/openvic-dataloader/v2script/ModifierGrammar.hpp | 30 | ||||
-rw-r--r-- | src/openvic-dataloader/v2script/Parser.cpp | 23 | ||||
-rw-r--r-- | src/openvic-dataloader/v2script/TriggerGrammar.hpp | 8 |
6 files changed, 151 insertions, 69 deletions
diff --git a/src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp b/src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp index 30f535a..a772a7c 100644 --- a/src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp +++ b/src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp @@ -1,23 +1,32 @@ #pragma once +#include "ModifierGrammar.hpp" #include "SimpleGrammar.hpp" #include "TriggerGrammar.hpp" #include <lexy/dsl.hpp> +#include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp> namespace ovdl::v2script::grammar { - constexpr auto modifier_keyword = LEXY_KEYWORD("modifier", lexy::dsl::inline_<Identifier>); - constexpr auto factor_keyword = LEXY_KEYWORD("factor", lexy::dsl::inline_<Identifier>); + struct AiBehaviorList { + static constexpr auto rule = lexy::dsl::list(lexy::dsl::p<FactorStatement> | lexy::dsl::p<ModifierStatement>); - struct AiModifierStatement { - static constexpr auto rule = - modifier_keyword >> - (lexy::dsl::equal_sign + - lexy::dsl::curly_bracketed.list( - (factor_keyword >> lexy::dsl::p<Identifier>) | - lexy::dsl::p<TriggerStatement>)); + static constexpr auto value = + lexy::as_list<std::vector<ast::NodePtr>> >> + lexy::callback<ast::NodePtr>( + [](auto&& list) { + return ast::make_node_ptr<ast::BehaviorListNode>(LEXY_MOV(list)); + }); }; - struct AiBehaviorList { - static constexpr auto rule = lexy::dsl::list((factor_keyword >> lexy::dsl::p<Identifier>) | lexy::dsl::p<AiModifierStatement>); + struct AiBehaviorBlock { + static constexpr auto rule = lexy::dsl::curly_bracketed.opt(lexy::dsl::p<AiBehaviorList>); + + static constexpr auto value = lexy::callback<ast::NodePtr>( + [](auto&& list) { + return LEXY_MOV(list); + }, + [](lexy::nullopt = {}) { + return nullptr; + }); }; }
\ No newline at end of file diff --git a/src/openvic-dataloader/v2script/DecisionGrammar.hpp b/src/openvic-dataloader/v2script/DecisionGrammar.hpp index 70e009f..3e77616 100644 --- a/src/openvic-dataloader/v2script/DecisionGrammar.hpp +++ b/src/openvic-dataloader/v2script/DecisionGrammar.hpp @@ -9,7 +9,10 @@ #include "SimpleGrammar.hpp" #include "TriggerGrammar.hpp" #include <lexy/callback.hpp> +#include <lexy/callback/adapter.hpp> +#include <lexy/callback/container.hpp> #include <lexy/dsl.hpp> +#include <lexy/dsl/option.hpp> #include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp> // Decision Grammar Definitions // @@ -17,30 +20,39 @@ namespace ovdl::v2script::grammar { ////////////////// // Macros ////////////////// -// Produces <KW_NAME>_keyword -#define OVDL_GRAMMAR_KEYWORD_DEFINE(KW_NAME) \ - static constexpr auto KW_NAME##_keyword = LEXY_KEYWORD(#KW_NAME, lexy::dsl::inline_<Identifier>) +// Produces <KW_NAME>_rule and <KW_NAME>_p +#define OVDL_GRAMMAR_KEYWORD_DEFINE(KW_NAME) \ + struct KW_NAME##_rule { \ + static constexpr auto keyword = LEXY_KEYWORD(#KW_NAME, lexy::dsl::inline_<Identifier>); \ + static constexpr auto rule = keyword >> lexy::dsl::equal_sign; \ + static constexpr auto value = lexy::noop; \ + }; \ + static constexpr auto KW_NAME##_p = lexy::dsl::p<KW_NAME##_rule> -// Produces <KW_NAME>_keyword and <KW_NAME>_flag and <KW_NAME>_too_many_error -#define OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(KW_NAME) \ - static constexpr auto KW_NAME##_keyword = LEXY_KEYWORD(#KW_NAME, lexy::dsl::inline_<Identifier>); \ - static constexpr auto KW_NAME##_flag = lexy::dsl::context_flag<struct KW_NAME##_context>; \ - struct KW_NAME##_too_many_error { \ - static constexpr auto name = "expected left side " #KW_NAME " to be found once"; \ - } - -// Produces <KW_NAME>_statement -#define OVDL_GRAMMAR_KEYWORD_STATEMENT(KW_NAME, ...) \ - constexpr auto KW_NAME##_statement = KW_NAME##_keyword >> (lexy::dsl::equal_sign + (__VA_ARGS__)) - -// Produces <KW_NAME>_statement -#define OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(KW_NAME, ...) \ - constexpr auto KW_NAME##_statement = KW_NAME##_keyword >> ((lexy::dsl::must(KW_NAME##_flag.is_reset()).error<KW_NAME##_too_many_error> + KW_NAME##_flag.set()) + lexy::dsl::equal_sign + (__VA_ARGS__)) +// Produces <KW_NAME>_rule and <KW_NAME>_p and <KW_NAME>_rule::flag and <KW_NAME>_rule::too_many_error +#define OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(KW_NAME) \ + struct KW_NAME##_rule { \ + static constexpr auto keyword = LEXY_KEYWORD(#KW_NAME, lexy::dsl::inline_<Identifier>); \ + static constexpr auto rule = keyword >> lexy::dsl::equal_sign; \ + static constexpr auto value = lexy::noop; \ + static constexpr auto flag = lexy::dsl::context_flag<struct KW_NAME##_context>; \ + struct too_many_error { \ + static constexpr auto name = "expected left side " #KW_NAME " to be found once"; \ + }; \ + }; \ + static constexpr auto KW_NAME##_p = lexy::dsl::p<KW_NAME##_rule> >> (lexy::dsl::must(KW_NAME##_rule::flag.is_reset()).error<KW_NAME##_rule::too_many_error> + KW_NAME##_rule::flag.set()) ////////////////// // Macros ////////////////// - struct DecisionStatement { + template<auto Production, typename AstNode> + struct _StringStatement { + static constexpr auto rule = Production >> (lexy::dsl::p<StringExpression> | lexy::dsl::p<Identifier>); + static constexpr auto value = lexy::forward<ast::NodePtr>; + }; + template<auto Production, typename AstNode> + static constexpr auto StringStatement = lexy::dsl::p<_StringStatement<Production, AstNode>>; + OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(potential); OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(allow); OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(effect); @@ -48,16 +60,15 @@ namespace ovdl::v2script::grammar { static constexpr auto rule = [] { constexpr auto create_flags = - potential_flag.create() + - allow_flag.create() + - effect_flag.create() + - ai_will_do_flag.create(); - constexpr auto check_flag = [](auto flag) { return flag.is_reset() + flag.set(); }; + potential_rule::flag.create() + + allow_rule::flag.create() + + effect_rule::flag.create() + + ai_will_do_rule::flag.create(); - OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(potential, lexy::dsl::curly_bracketed.opt(lexy::dsl::p<TriggerList>)); - OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(allow, lexy::dsl::curly_bracketed.opt(lexy::dsl::p<TriggerList>)); - OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(effect, lexy::dsl::curly_bracketed(lexy::dsl::p<EffectList>)); - OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(ai_will_do, lexy::dsl::curly_bracketed(lexy::dsl::p<AiBehaviorList>)); + constexpr auto potential_statement = potential_p >> lexy::dsl::p<TriggerBlock>; + constexpr auto allow_statement = allow_p >> lexy::dsl::p<TriggerBlock>; + constexpr auto effect_statement = effect_p >> lexy::dsl::p<TriggerBlock>; + constexpr auto ai_will_do_statement = ai_will_do_p >> lexy::dsl::p<AiBehaviorBlock>; return lexy::dsl::p<Identifier> >> (create_flags + lexy::dsl::equal_sign + @@ -69,16 +80,41 @@ namespace ovdl::v2script::grammar { lexy::dsl::p<SimpleAssignmentStatement>)); }(); - static constexpr auto value = lexy::callback<ast::NodePtr>([](auto name, lexy::nullopt = {}) { return LEXY_MOV(name); }, [](auto name, auto&& initalizer) { return make_node_ptr<ast::AssignNode>(LEXY_MOV(name), LEXY_MOV(initalizer)); }); + static constexpr auto value = + lexy::as_list<std::vector<ast::NodePtr>> >> + lexy::callback<ast::NodePtr>( + [](auto&& name, auto&& list) { + return ast::make_node_ptr<ast::DecisionNode>(LEXY_MOV(name), LEXY_MOV(list)); + }, + [](auto&& name, lexy::nullopt = {}) { + return ast::make_node_ptr<ast::DecisionNode>(LEXY_MOV(name)); + }); + }; + + struct DecisionList { + static constexpr auto rule = + LEXY_KEYWORD("political_decisions", lexy::dsl::inline_<Identifier>) >> + (lexy::dsl::equal_sign + lexy::dsl::curly_bracketed.opt_list(lexy::dsl::p<DecisionStatement>)); + + static constexpr auto value = + lexy::as_list<std::vector<ast::NodePtr>> >> + lexy::callback<ast::NodePtr>( + [](auto&& list) { + return ast::make_node_ptr<ast::DecisionListNode>(LEXY_MOV(list)); + }, + [](lexy::nullopt = {}) { + return nullptr; + }); }; struct DecisionFile { // Allow arbitrary spaces between individual tokens. static constexpr auto whitespace = whitespace_specifier | comment_specifier; - static constexpr auto rule = lexy::dsl::terminator(lexy::dsl::eof).list( // - (LEXY_KEYWORD("political_decisions", lexy::dsl::inline_<Identifier>) >> (lexy::dsl::equal_sign + lexy::dsl::curly_bracketed.opt_list(lexy::dsl::p<DecisionStatement>))) | // - lexy::dsl::p<SimpleAssignmentStatement>); + static constexpr auto rule = + lexy::dsl::terminator(lexy::dsl::eof).list( // + lexy::dsl::p<DecisionList> | // + lexy::dsl::p<SimpleAssignmentStatement>); static constexpr auto value = lexy::as_list<std::vector<ast::NodePtr>> >> lexy::new_<ast::FileNode, ast::NodePtr>; }; diff --git a/src/openvic-dataloader/v2script/EventGrammar.hpp b/src/openvic-dataloader/v2script/EventGrammar.hpp index 02b3e0c..216d645 100644 --- a/src/openvic-dataloader/v2script/EventGrammar.hpp +++ b/src/openvic-dataloader/v2script/EventGrammar.hpp @@ -6,6 +6,7 @@ #include "AiBehaviorGrammar.hpp" #include "EffectGrammar.hpp" +#include "ModifierGrammar.hpp" #include "SimpleGrammar.hpp" #include "TriggerGrammar.hpp" #include <lexy/callback.hpp> @@ -45,32 +46,12 @@ namespace ovdl::v2script::grammar { .map<LEXY_SYMBOL("country_event")>(ast::EventNode::Type::Country) .map<LEXY_SYMBOL("province_event")>(ast::EventNode::Type::Province); - struct EventFactor { - static constexpr auto rule = factor_keyword >> lexy::dsl::equal_sign + lexy::dsl::p<Identifier>; - static constexpr auto value = lexy::forward<ast::NodePtr>; - }; - - struct EventMtthModifierStatement { - static constexpr auto rule = - modifier_keyword >> - lexy::dsl::curly_bracketed.list( - lexy::dsl::p<EventFactor> | - lexy::dsl::p<TriggerStatement>); - - static constexpr auto value = - lexy::as_list<std::vector<ast::NodePtr>> >> - lexy::callback<ast::NodePtr>( - [](auto&& list) { - return make_node_ptr<ast::MtthModifierNode>(LEXY_MOV(list)); - }); - }; - struct EventMtthStatement { OVDL_GRAMMAR_KEYWORD_DEFINE(months); static constexpr auto rule = lexy::dsl::list( (months_p >> lexy::dsl::p<Identifier>) | - lexy::dsl::p<EventMtthModifierStatement>); + lexy::dsl::p<ModifierStatement>); static constexpr auto value = lexy::as_list<std::vector<ast::NodePtr>> >> @@ -88,7 +69,7 @@ namespace ovdl::v2script::grammar { constexpr auto create_flags = name_rule::flag.create() + ai_chance_rule::flag.create(); constexpr auto name_statement = name_p >> (lexy::dsl::p<StringExpression> | lexy::dsl::p<Identifier>); - constexpr auto ai_chance_statement = ai_chance_p >> lexy::dsl::curly_bracketed(lexy::dsl::p<EventFactor>); + constexpr auto ai_chance_statement = ai_chance_p >> lexy::dsl::curly_bracketed(lexy::dsl::p<AiBehaviorList>); return create_flags + lexy::dsl::list(name_statement | ai_chance_statement | lexy::dsl::p<EffectList>); }(); @@ -102,7 +83,6 @@ namespace ovdl::v2script::grammar { }; struct EventStatement { - template<auto Production, typename AstNode> struct _StringStatement { static constexpr auto rule = Production >> (lexy::dsl::p<StringExpression> | lexy::dsl::p<Identifier>); @@ -135,8 +115,6 @@ namespace ovdl::v2script::grammar { immediate_rule::flag.create() + mean_time_to_happen_rule::flag.create(); - constexpr auto string_value = lexy::dsl::p<StringExpression> | lexy::dsl::p<Identifier>; - constexpr auto id_statement = StringStatement<id_p, ast::IdNode>; constexpr auto title_statement = StringStatement<title_p, ast::TitleNode>; constexpr auto desc_statement = StringStatement<desc_p, ast::DescNode>; diff --git a/src/openvic-dataloader/v2script/ModifierGrammar.hpp b/src/openvic-dataloader/v2script/ModifierGrammar.hpp new file mode 100644 index 0000000..2b28712 --- /dev/null +++ b/src/openvic-dataloader/v2script/ModifierGrammar.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "SimpleGrammar.hpp" +#include "TriggerGrammar.hpp" +#include <lexy/dsl.hpp> + +namespace ovdl::v2script::grammar { + constexpr auto modifier_keyword = LEXY_KEYWORD("modifier", lexy::dsl::inline_<Identifier>); + constexpr auto factor_keyword = LEXY_KEYWORD("factor", lexy::dsl::inline_<Identifier>); + + struct FactorStatement { + static constexpr auto rule = factor_keyword >> lexy::dsl::equal_sign + lexy::dsl::p<Identifier>; + static constexpr auto value = lexy::forward<ast::NodePtr>; + }; + + struct ModifierStatement { + static constexpr auto rule = + modifier_keyword >> + lexy::dsl::curly_bracketed.list( + lexy::dsl::p<FactorStatement> | + lexy::dsl::p<TriggerStatement>); + + static constexpr auto value = + lexy::as_list<std::vector<ast::NodePtr>> >> + lexy::callback<ast::NodePtr>( + [](auto&& list) { + return make_node_ptr<ast::ModifierNode>(LEXY_MOV(list)); + }); + }; +}
\ No newline at end of file diff --git a/src/openvic-dataloader/v2script/Parser.cpp b/src/openvic-dataloader/v2script/Parser.cpp index 2177d8a..11d2e2c 100644 --- a/src/openvic-dataloader/v2script/Parser.cpp +++ b/src/openvic-dataloader/v2script/Parser.cpp @@ -14,6 +14,7 @@ #include "detail/NullBuff.hpp" #include "detail/OStreamOutputIterator.hpp" #include "detail/Warnings.hpp" +#include "v2script/DecisionGrammar.hpp" #include "v2script/EventGrammar.hpp" #include <lexy/action/parse.hpp> #include <lexy/encoding.hpp> @@ -206,6 +207,28 @@ bool Parser::event_parse() { return true; } +bool Parser::decision_parse() { + if (!_buffer_handler->is_valid()) { + return false; + } + + if (_buffer_handler->is_exclusive_utf8()) { + _warnings.push_back(warnings::make_utf8_warning(_file_path)); + } + + auto errors = _buffer_handler->parse<grammar::DecisionFile>(ovdl::detail::ReporError.path(_file_path).to(detail::OStreamOutputItertaor { _error_stream })); + if (errors) { + _errors.reserve(errors->size()); + for (auto& err : errors.value()) { + _has_fatal_error |= err.type == ParseError::Type::Fatal; + _errors.push_back(err); + } + return false; + } + _file_node.reset(static_cast<ast::FileNode*>(_buffer_handler->get_root().release())); + return true; +} + bool Parser::has_error() const { return !_errors.empty(); } diff --git a/src/openvic-dataloader/v2script/TriggerGrammar.hpp b/src/openvic-dataloader/v2script/TriggerGrammar.hpp index 5b04e5b..514da49 100644 --- a/src/openvic-dataloader/v2script/TriggerGrammar.hpp +++ b/src/openvic-dataloader/v2script/TriggerGrammar.hpp @@ -29,6 +29,12 @@ namespace ovdl::v2script::grammar { struct TriggerBlock { static constexpr auto rule = lexy::dsl::curly_bracketed.opt(lexy::dsl::p<TriggerList>); - static constexpr auto value = lexy::forward<ast::NodePtr>; + static constexpr auto value = lexy::callback<ast::NodePtr>( + [](auto&& list) { + return LEXY_MOV(list); + }, + [](lexy::nullopt = {}) { + return nullptr; + }); }; }
\ No newline at end of file |