#pragma once #include #include #include #include "AiBehaviorGrammar.hpp" #include "EffectGrammar.hpp" #include "SimpleGrammar.hpp" #include "TriggerGrammar.hpp" #include #include #include // Event Grammar Definitions // namespace ovdl::v2script::grammar { ////////////////// // Macros ////////////////// // Produces _keyword #define OVDL_GRAMMAR_KEYWORD_DEFINE(KW_NAME) \ static constexpr auto KW_NAME##_keyword = LEXY_KEYWORD(#KW_NAME, lexy::dsl::inline_) // Produces _keyword and _flag and _too_many_error #define OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(KW_NAME) \ static constexpr auto KW_NAME##_keyword = LEXY_KEYWORD(#KW_NAME, lexy::dsl::inline_); \ static constexpr auto KW_NAME##_flag = lexy::dsl::context_flag; \ struct KW_NAME##_too_many_error { \ static constexpr auto name = "expected left side " #KW_NAME " to be found once"; \ } // Produces _statement #define OVDL_GRAMMAR_KEYWORD_STATEMENT(KW_NAME, ...) \ constexpr auto KW_NAME##_statement = KW_NAME##_keyword >> (lexy::dsl::equal_sign + (__VA_ARGS__)) // Produces _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##_flag.set()) + lexy::dsl::equal_sign + (__VA_ARGS__)) ////////////////// // Macros ////////////////// static constexpr auto event_symbols = lexy::symbol_table // .map(ast::EventNode::Type::Country) .map(ast::EventNode::Type::Province); struct EventMeanTimeToHappenModifierStatement { static constexpr auto rule = modifier_keyword >> lexy::dsl::curly_bracketed.list( (factor_keyword >> lexy::dsl::p) | lexy::dsl::p); }; struct EventMeanTimeToHappenStatement { static constexpr auto months_keyword = LEXY_KEYWORD("months", lexy::dsl::inline_); static constexpr auto rule = lexy::dsl::list( (months_keyword >> lexy::dsl::p) | lexy::dsl::p); }; 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 | lexy::dsl::p); return create_flags + lexy::dsl::list(name_statement | lexy::dsl::p); }(); }; 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 | lexy::dsl::p; 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)); OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(mean_time_to_happen, lexy::dsl::curly_bracketed(lexy::dsl::p)); OVDL_GRAMMAR_KEYWORD_STATEMENT(trigger, lexy::dsl::curly_bracketed.opt(lexy::dsl::p)); OVDL_GRAMMAR_KEYWORD_STATEMENT(option, lexy::dsl::curly_bracketed(lexy::dsl::p)); return lexy::dsl::symbol(lexy::dsl::inline_) >> (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)); }(); static constexpr auto value = lexy::callback([](auto name, lexy::nullopt = {}) { return LEXY_MOV(name); }, [](auto name, auto&& initalizer) { return make_node_ptr(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 | lexy::dsl::p); static constexpr auto value = lexy::as_list> >> lexy::new_; }; #undef OVDL_GRAMMAR_KEYWORD_DEFINE #undef OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE #undef OVDL_GRAMMAR_KEYWORD_STATEMENT #undef OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT }