aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Spartan322 <Megacake1234@gmail.com>2023-08-20 09:58:07 +0200
committer Spartan322 <Megacake1234@gmail.com>2023-08-20 09:58:07 +0200
commitb1bc7d520f09430c8d2372c6541ce23ec8099e13 (patch)
treea28708ccff8332e0233e6f578d988c68e0d589c4
parent8ebcba11d103ebe8ab259b311e874e1bac05dfd3 (diff)
Add the rough draft grammar for events and decisions
-rw-r--r--include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp27
-rw-r--r--src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp22
-rw-r--r--src/openvic-dataloader/v2script/DecisionGrammar.hpp76
-rw-r--r--src/openvic-dataloader/v2script/EffectGrammar.hpp14
-rw-r--r--src/openvic-dataloader/v2script/EventGrammar.hpp129
-rw-r--r--src/openvic-dataloader/v2script/SimpleGrammar.hpp14
-rw-r--r--src/openvic-dataloader/v2script/TriggerGrammar.hpp14
7 files changed, 296 insertions, 0 deletions
diff --git a/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp b/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp
index 80485b7..5faeb80 100644
--- a/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp
+++ b/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp
@@ -167,6 +167,33 @@ namespace ovdl::v2script::ast {
}
})
};
+
+ struct EventNode final : public Node {
+ enum class Type {
+ Country,
+ Province
+ } _type;
+ std::vector<NodeUPtr> _statements;
+ explicit EventNode(Type type, std::vector<NodePtr> statements)
+ : _type(type),
+ _statements(make_node_ptr_vector(statements)) {
+ }
+
+ OVDL_TYPE_DEFINE_SELF;
+ OVDL_RT_TYPE_DEF;
+
+ OVDL_PRINT_FUNC_DEF({
+ switch (_type) {
+ case Type::Country: stream << "country_event"; break;
+ case Type::Province: stream << "province_event"; break;
+ }
+ stream << " = {";
+ for (auto& statement : _statements) {
+ statement->print(stream);
+ }
+ stream << "}";
+ })
+ };
}
#undef OVDL_PRINT_FUNC_DECL
diff --git a/src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp b/src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp
new file mode 100644
index 0000000..f3e1994
--- /dev/null
+++ b/src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp
@@ -0,0 +1,22 @@
+#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 AiModifierStatement {
+ static constexpr auto rule =
+ modifier_keyword >>
+ lexy::dsl::curly_bracketed.list(
+ (factor_keyword >> lexy::dsl::p<Identifier>) |
+ lexy::dsl::p<TriggerStatement>);
+ };
+
+ struct AiBehaviorList {
+ static constexpr auto rule = lexy::dsl::list((factor_keyword >> lexy::dsl::p<Identifier>) | lexy::dsl::p<AiModifierStatement>);
+ };
+} \ No newline at end of file
diff --git a/src/openvic-dataloader/v2script/DecisionGrammar.hpp b/src/openvic-dataloader/v2script/DecisionGrammar.hpp
index ebc9ad2..70e009f 100644
--- a/src/openvic-dataloader/v2script/DecisionGrammar.hpp
+++ b/src/openvic-dataloader/v2script/DecisionGrammar.hpp
@@ -4,11 +4,87 @@
#include <string>
#include <vector>
+#include "AiBehaviorGrammar.hpp"
+#include "EffectGrammar.hpp"
+#include "SimpleGrammar.hpp"
+#include "TriggerGrammar.hpp"
#include <lexy/callback.hpp>
#include <lexy/dsl.hpp>
#include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp>
// Decision Grammar Definitions //
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>_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__))
+ //////////////////
+ // Macros
+ //////////////////
+
+ struct DecisionStatement {
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(potential);
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(allow);
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(effect);
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(ai_will_do);
+
+ 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(); };
+
+ 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>));
+
+ return lexy::dsl::p<Identifier> >>
+ (create_flags + lexy::dsl::equal_sign +
+ lexy::dsl::curly_bracketed.list(
+ potential_statement |
+ allow_statement |
+ effect_statement |
+ ai_will_do_statement |
+ 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)); });
+ };
+
+ 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 value = lexy::as_list<std::vector<ast::NodePtr>> >> lexy::new_<ast::FileNode, ast::NodePtr>;
+ };
+
+#undef OVDL_GRAMMAR_KEYWORD_DEFINE
+#undef OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE
+#undef OVDL_GRAMMAR_KEYWORD_STATEMENT
+#undef OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT
} \ No newline at end of file
diff --git a/src/openvic-dataloader/v2script/EffectGrammar.hpp b/src/openvic-dataloader/v2script/EffectGrammar.hpp
new file mode 100644
index 0000000..4ee19dd
--- /dev/null
+++ b/src/openvic-dataloader/v2script/EffectGrammar.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "SimpleGrammar.hpp"
+#include <lexy/dsl.hpp>
+
+namespace ovdl::v2script::grammar {
+ struct EffectStatement {
+ static constexpr auto rule = lexy::dsl::p<SimpleAssignmentStatement>;
+ };
+
+ struct EffectList {
+ static constexpr auto rule = lexy::dsl::list(lexy::dsl::p<EffectStatement>);
+ };
+} \ No newline at end of file
diff --git a/src/openvic-dataloader/v2script/EventGrammar.hpp b/src/openvic-dataloader/v2script/EventGrammar.hpp
index 7ab40d4..21dd66b 100644
--- a/src/openvic-dataloader/v2script/EventGrammar.hpp
+++ b/src/openvic-dataloader/v2script/EventGrammar.hpp
@@ -4,11 +4,140 @@
#include <string>
#include <vector>
+#include "AiBehaviorGrammar.hpp"
+#include "EffectGrammar.hpp"
+#include "SimpleGrammar.hpp"
+#include "TriggerGrammar.hpp"
#include <lexy/callback.hpp>
#include <lexy/dsl.hpp>
#include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp>
// Event Grammar Definitions //
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>_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__))
+ //////////////////
+ // Macros
+ //////////////////
+ static constexpr auto event_symbols = lexy::symbol_table<ast::EventNode::Type> //
+ .map<LEXY_SYMBOL("country_event")>(ast::EventNode::Type::Country)
+ .map<LEXY_SYMBOL("province_event")>(ast::EventNode::Type::Province);
+
+ struct EventMeanTimeToHappenModifierStatement {
+ static constexpr auto rule =
+ modifier_keyword >>
+ lexy::dsl::curly_bracketed.list(
+ (factor_keyword >> lexy::dsl::p<Identifier>) |
+ lexy::dsl::p<TriggerStatement>);
+ };
+
+ struct EventMeanTimeToHappenStatement {
+ static constexpr auto months_keyword = LEXY_KEYWORD("months", lexy::dsl::inline_<Identifier>);
+
+ static constexpr auto rule = lexy::dsl::list(
+ (months_keyword >> lexy::dsl::p<Identifier>) |
+ lexy::dsl::p<EventMeanTimeToHappenModifierStatement>);
+ };
+
+ struct EventOptionList {
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(name);
+
+ static constexpr auto rule = [] {
+ constexpr auto create_flags = name_flag.create();
+
+ OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(name, lexy::dsl::p<StringExpression> | lexy::dsl::p<Identifier>);
+
+ return create_flags + lexy::dsl::list(name_statement | lexy::dsl::p<EffectStatement>);
+ }();
+ };
+
+ struct EventStatement {
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(id);
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(title);
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(desc);
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(picture);
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(is_triggered_only);
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(fire_only_once);
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(immediate);
+ OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(mean_time_to_happen);
+ OVDL_GRAMMAR_KEYWORD_DEFINE(trigger);
+ OVDL_GRAMMAR_KEYWORD_DEFINE(option);
+
+ static constexpr auto rule = [] {
+ constexpr auto create_flags =
+ id_flag.create() +
+ title_flag.create() +
+ desc_flag.create() +
+ picture_flag.create() +
+ is_triggered_only_flag.create() +
+ fire_only_once_flag.create() +
+ immediate_flag.create() +
+ mean_time_to_happen_flag.create();
+
+ constexpr auto string_value = lexy::dsl::p<StringExpression> | lexy::dsl::p<Identifier>;
+
+ OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(id, string_value);
+ OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(title, string_value);
+ OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(desc, string_value);
+ OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(picture, string_value);
+ OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(is_triggered_only, string_value);
+ OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(fire_only_once, string_value);
+ OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(immediate, lexy::dsl::curly_bracketed.opt(lexy::dsl::p<EffectList>));
+ OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(mean_time_to_happen, lexy::dsl::curly_bracketed(lexy::dsl::p<EventMeanTimeToHappenStatement>));
+
+ OVDL_GRAMMAR_KEYWORD_STATEMENT(trigger, lexy::dsl::curly_bracketed.opt(lexy::dsl::p<TriggerList>));
+ OVDL_GRAMMAR_KEYWORD_STATEMENT(option, lexy::dsl::curly_bracketed(lexy::dsl::p<EventOptionList>));
+
+ return lexy::dsl::symbol<event_symbols>(lexy::dsl::inline_<Identifier>) >>
+ (create_flags + lexy::dsl::equal_sign +
+ lexy::dsl::curly_bracketed.opt_list(
+ id_statement |
+ title_statement |
+ desc_statement |
+ picture_statement |
+ is_triggered_only_statement |
+ fire_only_once_statement |
+ immediate_statement |
+ mean_time_to_happen_statement |
+ trigger_statement |
+ option_statement |
+ 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)); });
+ };
+
+ struct EventFile {
+ // 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::dsl::p<EventStatement> | lexy::dsl::p<SimpleAssignmentStatement>);
+
+ static constexpr auto value = lexy::as_list<std::vector<ast::NodePtr>> >> lexy::new_<ast::FileNode, ast::NodePtr>;
+ };
+
+#undef OVDL_GRAMMAR_KEYWORD_DEFINE
+#undef OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE
+#undef OVDL_GRAMMAR_KEYWORD_STATEMENT
+#undef OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT
} \ No newline at end of file
diff --git a/src/openvic-dataloader/v2script/SimpleGrammar.hpp b/src/openvic-dataloader/v2script/SimpleGrammar.hpp
index 48a80ce..6849fe2 100644
--- a/src/openvic-dataloader/v2script/SimpleGrammar.hpp
+++ b/src/openvic-dataloader/v2script/SimpleGrammar.hpp
@@ -1,3 +1,5 @@
+#pragma once
+
#include <memory>
#include <string>
#include <vector>
@@ -57,6 +59,18 @@ namespace ovdl::v2script::grammar {
static constexpr auto value = lexy::as_string<std::string> >> lexy::new_<ast::StringNode, ast::NodePtr>;
};
+ struct SimpleAssignmentStatement {
+ static constexpr auto rule =
+ lexy::dsl::p<Identifier> >>
+ lexy::dsl::equal_sign +
+ (lexy::dsl::p<Identifier> | lexy::dsl::p<StringExpression> | lexy::dsl::recurse_branch<StatementListBlock>);
+
+ static constexpr auto value = lexy::callback<ast::NodePtr>(
+ [](auto name, auto&& initalizer) {
+ return make_node_ptr<ast::AssignNode>(LEXY_MOV(name), LEXY_MOV(initalizer));
+ });
+ };
+
struct AssignmentStatement {
static constexpr auto rule =
lexy::dsl::p<Identifier> >>
diff --git a/src/openvic-dataloader/v2script/TriggerGrammar.hpp b/src/openvic-dataloader/v2script/TriggerGrammar.hpp
new file mode 100644
index 0000000..6f3436b
--- /dev/null
+++ b/src/openvic-dataloader/v2script/TriggerGrammar.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "SimpleGrammar.hpp"
+#include <lexy/dsl.hpp>
+
+namespace ovdl::v2script::grammar {
+ struct TriggerStatement {
+ static constexpr auto rule = lexy::dsl::p<SimpleAssignmentStatement>;
+ };
+
+ struct TriggerList {
+ static constexpr auto rule = lexy::dsl::list(lexy::dsl::p<TriggerStatement>);
+ };
+} \ No newline at end of file