diff options
author | Spartan322 <Megacake1234@gmail.com> | 2023-08-22 20:30:59 +0200 |
---|---|---|
committer | Spartan322 <Megacake1234@gmail.com> | 2023-08-22 20:30:59 +0200 |
commit | dabf33050b6287fa7217858cb6021e1105f96894 (patch) | |
tree | a5f7b3e52e296a41ea9688b50ce53a8f495c4f13 | |
parent | b1bc7d520f09430c8d2372c6541ce23ec8099e13 (diff) |
Add event_parse to Parser
Move ostream_output_iterator to detail/OStreamOutputIterator.hpp
-rw-r--r-- | include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp | 140 | ||||
-rw-r--r-- | include/openvic-dataloader/v2script/Parser.hpp | 1 | ||||
-rw-r--r-- | src/openvic-dataloader/detail/OStreamOutputIterator.hpp | 21 | ||||
-rw-r--r-- | src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp | 7 | ||||
-rw-r--r-- | src/openvic-dataloader/v2script/EffectGrammar.hpp | 30 | ||||
-rw-r--r-- | src/openvic-dataloader/v2script/EventGrammar.hpp | 145 | ||||
-rw-r--r-- | src/openvic-dataloader/v2script/Parser.cpp | 34 | ||||
-rw-r--r-- | src/openvic-dataloader/v2script/SimpleGrammar.hpp | 5 | ||||
-rw-r--r-- | src/openvic-dataloader/v2script/TriggerGrammar.hpp | 24 |
9 files changed, 312 insertions, 95 deletions
diff --git a/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp b/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp index 5faeb80..a27c237 100644 --- a/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp +++ b/include/openvic-dataloader/v2script/AbstractSyntaxTree.hpp @@ -77,38 +77,46 @@ namespace ovdl::v2script::ast { std::vector<NodeUPtr> result; result.reserve(ptrs.size()); for (auto&& p : ptrs) { + if (p == nullptr) continue; result.push_back(NodeUPtr(p)); } return result; } - struct IdentifierNode final : public Node { + struct AbstractStringNode : public Node { std::string _name; - explicit IdentifierNode(std::string name) - : _name(std::move(name)) { - } - + explicit AbstractStringNode(std::string&& name) : _name(std::move(name)) {} OVDL_TYPE_DEFINE_SELF; OVDL_RT_TYPE_DEF; - OVDL_PRINT_FUNC_DEF({ stream << _name.c_str(); }) }; - struct StringNode final : public Node { - std::string _name; - explicit StringNode(std::string name) - : _name(std::move(name)) { - } +#define OVDL_AST_STRING_NODE(NAME) \ + struct NAME final : public AbstractStringNode { \ + explicit NAME(std::string&& name) : AbstractStringNode(std::move(name)) {} \ + OVDL_TYPE_DEFINE_SELF; \ + OVDL_RT_TYPE_DEF; \ + OVDL_PRINT_FUNC_DEF({ \ + stream << _name.c_str(); \ + }) \ + } - OVDL_TYPE_DEFINE_SELF; - OVDL_RT_TYPE_DEF; + OVDL_AST_STRING_NODE(IdentifierNode); + OVDL_AST_STRING_NODE(FactorNode); + OVDL_AST_STRING_NODE(MonthNode); + OVDL_AST_STRING_NODE(NameNode); + OVDL_AST_STRING_NODE(StringNode); + OVDL_AST_STRING_NODE(FireOnlyNode); - OVDL_PRINT_FUNC_DEF({ - stream << '"' << _name.c_str() << '"'; - }) - }; + OVDL_AST_STRING_NODE(IdNode); + OVDL_AST_STRING_NODE(TitleNode); + OVDL_AST_STRING_NODE(DescNode); + OVDL_AST_STRING_NODE(PictureNode); + OVDL_AST_STRING_NODE(IsTriggeredNode); + +#undef OVDL_AST_STRING_NODE struct AssignNode final : public Node { std::string _name; @@ -129,15 +137,11 @@ namespace ovdl::v2script::ast { }) }; - struct ListNode final : public Node { + struct AbstractListNode : public Node { std::vector<NodeUPtr> _statements; - explicit ListNode(std::vector<NodePtr> statements = std::vector<NodePtr> {}) - : _statements(make_node_ptr_vector(statements)) { - } - + AbstractListNode(std::vector<NodeUPtr>&& statements) : _statements(std::move(statements)) {} OVDL_TYPE_DEFINE_SELF; OVDL_RT_TYPE_DEF; - OVDL_PRINT_FUNC_DEF({ stream << '{'; for (int i = 0; i < _statements.size(); i++) { @@ -150,6 +154,30 @@ namespace ovdl::v2script::ast { }) }; +#define OVDL_AST_LIST_NODE(NAME) \ + struct NAME final : public AbstractListNode { \ + explicit NAME(std::vector<NodePtr> statements = std::vector<NodePtr> {}) : AbstractListNode(make_node_ptr_vector(statements)) {} \ + OVDL_TYPE_DEFINE_SELF; \ + OVDL_RT_TYPE_DEF; \ + OVDL_PRINT_FUNC_DEF({ \ + stream << '{'; \ + for (int i = 0; i < _statements.size(); i++) { \ + auto& statement = _statements[i]; \ + statement->print(stream); \ + if (i + 1 != _statements.size()) \ + stream << ' '; \ + } \ + stream << '}'; \ + }) \ + } + + OVDL_AST_LIST_NODE(ListNode); + OVDL_AST_LIST_NODE(MtthModifierNode); + OVDL_AST_LIST_NODE(MtthNode); + OVDL_AST_LIST_NODE(EventOptionNode); + +#undef OVDL_AST_LIST_NODE + struct FileNode final : public Node { std::vector<NodeUPtr> _statements; FileNode() {} @@ -174,7 +202,7 @@ namespace ovdl::v2script::ast { Province } _type; std::vector<NodeUPtr> _statements; - explicit EventNode(Type type, std::vector<NodePtr> statements) + explicit EventNode(Type type, std::vector<NodePtr> statements = {}) : _type(type), _statements(make_node_ptr_vector(statements)) { } @@ -194,6 +222,70 @@ namespace ovdl::v2script::ast { stream << "}"; }) }; + + struct EventMtthModifierNode final : public Node { + NodeUPtr _factor_value; + std::vector<NodeUPtr> _statements; + EventMtthModifierNode() {} + + OVDL_TYPE_DEFINE_SELF; + OVDL_RT_TYPE_DEF; + + OVDL_PRINT_FUNC_DEF({ + stream << "factor = "; + _factor_value->print(stream); + stream << ' '; + for (auto& statement : _statements) { + statement->print(stream); + } + }) + }; + + // Packed single case + struct ExecutionNode final : public Node { + enum class Type { + Effect, + Trigger + } _type; + std::string _name; + NodeUPtr _initializer; + explicit ExecutionNode(Type type, NodePtr name, NodePtr init) + : _type(type), + _initializer(std::move(init)) { + if (name->is_type<IdentifierNode>()) { + _name = cast_node_ptr<IdentifierNode>(name)._name; + } + } + + OVDL_TYPE_DEFINE_SELF; + OVDL_RT_TYPE_DEF; + + OVDL_PRINT_FUNC_DEF({ + stream << _name.c_str() << " = "; + _initializer->print(stream); + }) + }; + + struct ExecutionListNode final : public Node { + ExecutionNode::Type _type; + std::vector<NodeUPtr> _statements; + explicit ExecutionListNode(ExecutionNode::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({ + stream << "{"; + for (auto& statement : _statements) { + statement->print(stream); + } + stream << "}"; + }) + }; + } #undef OVDL_PRINT_FUNC_DECL diff --git a/include/openvic-dataloader/v2script/Parser.hpp b/include/openvic-dataloader/v2script/Parser.hpp index e971cdb..4f67e22 100644 --- a/include/openvic-dataloader/v2script/Parser.hpp +++ b/include/openvic-dataloader/v2script/Parser.hpp @@ -33,6 +33,7 @@ namespace ovdl::v2script { void set_error_log_to(std::basic_ostream<char>& stream); bool simple_parse(); + bool event_parse(); bool has_error() const; bool has_fatal_error() const; diff --git a/src/openvic-dataloader/detail/OStreamOutputIterator.hpp b/src/openvic-dataloader/detail/OStreamOutputIterator.hpp new file mode 100644 index 0000000..c71c105 --- /dev/null +++ b/src/openvic-dataloader/detail/OStreamOutputIterator.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include <ostream> + +namespace ovdl::detail { + struct OStreamOutputItertaor { + std::reference_wrapper<std::ostream> _stream; + + auto operator*() const noexcept { + return *this; + } + auto operator++(int) const noexcept { + return *this; + } + + OStreamOutputItertaor& operator=(char c) { + _stream.get().put(c); + return *this; + } + }; +}
\ No newline at end of file diff --git a/src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp b/src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp index f3e1994..30f535a 100644 --- a/src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp +++ b/src/openvic-dataloader/v2script/AiBehaviorGrammar.hpp @@ -11,9 +11,10 @@ namespace ovdl::v2script::grammar { struct AiModifierStatement { static constexpr auto rule = modifier_keyword >> - lexy::dsl::curly_bracketed.list( - (factor_keyword >> lexy::dsl::p<Identifier>) | - lexy::dsl::p<TriggerStatement>); + (lexy::dsl::equal_sign + + lexy::dsl::curly_bracketed.list( + (factor_keyword >> lexy::dsl::p<Identifier>) | + lexy::dsl::p<TriggerStatement>)); }; struct AiBehaviorList { diff --git a/src/openvic-dataloader/v2script/EffectGrammar.hpp b/src/openvic-dataloader/v2script/EffectGrammar.hpp index 4ee19dd..71697c4 100644 --- a/src/openvic-dataloader/v2script/EffectGrammar.hpp +++ b/src/openvic-dataloader/v2script/EffectGrammar.hpp @@ -1,14 +1,40 @@ #pragma once #include "SimpleGrammar.hpp" +#include <lexy/callback.hpp> #include <lexy/dsl.hpp> +#include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp> namespace ovdl::v2script::grammar { struct EffectStatement { - static constexpr auto rule = lexy::dsl::p<SimpleAssignmentStatement>; + static constexpr auto rule = lexy::dsl::inline_<SimpleAssignmentStatement>; + + static constexpr auto value = lexy::callback<ast::NodePtr>( + [](auto name, auto&& initalizer) { + return ast::make_node_ptr<ast::ExecutionNode>(ast::ExecutionNode::Type::Effect, LEXY_MOV(name), LEXY_MOV(initalizer)); + }); }; struct EffectList { - static constexpr auto rule = lexy::dsl::list(lexy::dsl::p<EffectStatement>); + static constexpr auto rule = lexy::dsl::list(lexy::dsl::p<SimpleAssignmentStatement>); + + static constexpr auto value = + lexy::as_list<std::vector<ast::NodePtr>> >> + lexy::callback<ast::NodePtr>( + [](auto&& list) { + return ast::make_node_ptr<ast::ExecutionListNode>(ast::ExecutionNode::Type::Effect, LEXY_MOV(list)); + }); + }; + + struct EffectBlock { + static constexpr auto rule = lexy::dsl::curly_bracketed.opt(lexy::dsl::p<EffectList>); + + 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/EventGrammar.hpp b/src/openvic-dataloader/v2script/EventGrammar.hpp index 21dd66b..02b3e0c 100644 --- a/src/openvic-dataloader/v2script/EventGrammar.hpp +++ b/src/openvic-dataloader/v2script/EventGrammar.hpp @@ -17,25 +17,27 @@ 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__)) +// 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>_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 ////////////////// @@ -43,35 +45,72 @@ namespace ovdl::v2script::grammar { .map<LEXY_SYMBOL("country_event")>(ast::EventNode::Type::Country) .map<LEXY_SYMBOL("province_event")>(ast::EventNode::Type::Province); - struct EventMeanTimeToHappenModifierStatement { + 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( - (factor_keyword >> lexy::dsl::p<Identifier>) | + 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 EventMeanTimeToHappenStatement { - static constexpr auto months_keyword = LEXY_KEYWORD("months", lexy::dsl::inline_<Identifier>); + struct EventMtthStatement { + OVDL_GRAMMAR_KEYWORD_DEFINE(months); static constexpr auto rule = lexy::dsl::list( - (months_keyword >> lexy::dsl::p<Identifier>) | - lexy::dsl::p<EventMeanTimeToHappenModifierStatement>); + (months_p >> lexy::dsl::p<Identifier>) | + lexy::dsl::p<EventMtthModifierStatement>); + + static constexpr auto value = + lexy::as_list<std::vector<ast::NodePtr>> >> + lexy::callback<ast::NodePtr>( + [](auto&& list) { + return ast::make_node_ptr<ast::MtthNode>(LEXY_MOV(list)); + }); }; struct EventOptionList { OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(name); + OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(ai_chance); static constexpr auto rule = [] { - constexpr auto create_flags = name_flag.create(); + constexpr auto create_flags = name_rule::flag.create() + ai_chance_rule::flag.create(); - OVDL_GRAMMAR_KEYWORD_FLAG_STATEMENT(name, lexy::dsl::p<StringExpression> | lexy::dsl::p<Identifier>); + 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>); - return create_flags + lexy::dsl::list(name_statement | lexy::dsl::p<EffectStatement>); + return create_flags + lexy::dsl::list(name_statement | ai_chance_statement | lexy::dsl::p<EffectList>); }(); + + static constexpr auto value = + lexy::as_list<std::vector<ast::NodePtr>> >> + lexy::callback<ast::NodePtr>( + [](auto&& list) { + return ast::make_node_ptr<ast::EventOptionNode>(LEXY_MOV(list)); + }); }; struct EventStatement { + + 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(id); OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(title); OVDL_GRAMMAR_KEYWORD_FLAG_DEFINE(desc); @@ -84,31 +123,33 @@ namespace ovdl::v2script::grammar { OVDL_GRAMMAR_KEYWORD_DEFINE(option); static constexpr auto rule = [] { + constexpr auto symbol_value = lexy::dsl::symbol<event_symbols>(lexy::dsl::inline_<Identifier>); + 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(); + id_rule::flag.create() + + title_rule::flag.create() + + desc_rule::flag.create() + + picture_rule::flag.create() + + is_triggered_only_rule::flag.create() + + fire_only_once_rule::flag.create() + + immediate_rule::flag.create() + + mean_time_to_happen_rule::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>)); + 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>; + constexpr auto picture_statement = StringStatement<picture_p, ast::PictureNode>; + constexpr auto is_triggered_only_statement = StringStatement<is_triggered_only_p, ast::IsTriggeredNode>; + constexpr auto fire_only_once_statement = StringStatement<fire_only_once_p, ast::FireOnlyNode>; + constexpr auto immediate_statement = immediate_p >> lexy::dsl::p<EffectBlock>; + constexpr auto mean_time_to_happen_statement = mean_time_to_happen_p >> lexy::dsl::curly_bracketed(lexy::dsl::p<EventMtthStatement>); - 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>)); + constexpr auto trigger_statement = trigger_p >> lexy::dsl::curly_bracketed.opt(lexy::dsl::p<TriggerList>); + constexpr auto option_statement = option_p >> lexy::dsl::curly_bracketed(lexy::dsl::p<EventOptionList>); - return lexy::dsl::symbol<event_symbols>(lexy::dsl::inline_<Identifier>) >> + return symbol_value >> (create_flags + lexy::dsl::equal_sign + lexy::dsl::curly_bracketed.opt_list( id_statement | @@ -124,7 +165,15 @@ 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& type, auto&& list) { + return ast::make_node_ptr<ast::EventNode>(type, LEXY_MOV(list)); + }, + [](auto& type, lexy::nullopt = {}) { + return ast::make_node_ptr<ast::EventNode>(type); + }); }; struct EventFile { diff --git a/src/openvic-dataloader/v2script/Parser.cpp b/src/openvic-dataloader/v2script/Parser.cpp index 7df9b99..2177d8a 100644 --- a/src/openvic-dataloader/v2script/Parser.cpp +++ b/src/openvic-dataloader/v2script/Parser.cpp @@ -12,7 +12,9 @@ #include "detail/Errors.hpp" #include "detail/LexyReportError.hpp" #include "detail/NullBuff.hpp" +#include "detail/OStreamOutputIterator.hpp" #include "detail/Warnings.hpp" +#include "v2script/EventGrammar.hpp" #include <lexy/action/parse.hpp> #include <lexy/encoding.hpp> #include <lexy/input/buffer.hpp> @@ -165,27 +167,33 @@ bool Parser::simple_parse() { return false; } - struct ostream_output_iterator { - std::reference_wrapper<std::ostream> _stream; + if (_buffer_handler->is_exclusive_utf8()) { + _warnings.push_back(warnings::make_utf8_warning(_file_path)); + } - auto operator*() const noexcept { - return *this; - } - auto operator++(int) const noexcept { - return *this; + auto errors = _buffer_handler->parse<grammar::File>(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; +} - ostream_output_iterator& operator=(char c) { - _stream.get().put(c); - return *this; - } - }; +bool Parser::event_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::File>(ovdl::detail::ReporError.path(_file_path).to(ostream_output_iterator { _error_stream })); + auto errors = _buffer_handler->parse<grammar::EventFile>(ovdl::detail::ReporError.path(_file_path).to(detail::OStreamOutputItertaor { _error_stream })); if (errors) { _errors.reserve(errors->size()); for (auto& err : errors.value()) { diff --git a/src/openvic-dataloader/v2script/SimpleGrammar.hpp b/src/openvic-dataloader/v2script/SimpleGrammar.hpp index 6849fe2..9c95914 100644 --- a/src/openvic-dataloader/v2script/SimpleGrammar.hpp +++ b/src/openvic-dataloader/v2script/SimpleGrammar.hpp @@ -90,9 +90,8 @@ namespace ovdl::v2script::grammar { struct StatementListBlock { static constexpr auto rule = - lexy::dsl::curly_bracketed.open() >> - lexy::dsl::opt(lexy::dsl::list(lexy::dsl::p<AssignmentStatement>)) + lexy::dsl::opt(lexy::dsl::semicolon) + - lexy::dsl::curly_bracketed.close(); + lexy::dsl::curly_bracketed( + lexy::dsl::opt(lexy::dsl::list(lexy::dsl::p<AssignmentStatement>)) + lexy::dsl::opt(lexy::dsl::semicolon)); static constexpr auto value = lexy::as_list<std::vector<ast::NodePtr>> >> diff --git a/src/openvic-dataloader/v2script/TriggerGrammar.hpp b/src/openvic-dataloader/v2script/TriggerGrammar.hpp index 6f3436b..5b04e5b 100644 --- a/src/openvic-dataloader/v2script/TriggerGrammar.hpp +++ b/src/openvic-dataloader/v2script/TriggerGrammar.hpp @@ -1,14 +1,34 @@ #pragma once #include "SimpleGrammar.hpp" +#include <lexy/callback.hpp> #include <lexy/dsl.hpp> +#include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp> namespace ovdl::v2script::grammar { struct TriggerStatement { - static constexpr auto rule = lexy::dsl::p<SimpleAssignmentStatement>; + static constexpr auto rule = lexy::dsl::inline_<SimpleAssignmentStatement>; + + static constexpr auto value = lexy::callback<ast::NodePtr>( + [](auto name, auto&& initalizer) { + return ast::make_node_ptr<ast::ExecutionNode>(ast::ExecutionNode::Type::Trigger, LEXY_MOV(name), LEXY_MOV(initalizer)); + }); }; struct TriggerList { - static constexpr auto rule = lexy::dsl::list(lexy::dsl::p<TriggerStatement>); + static constexpr auto rule = lexy::dsl::list(lexy::dsl::p<SimpleAssignmentStatement>); + + static constexpr auto value = + lexy::as_list<std::vector<ast::NodePtr>> >> + lexy::callback<ast::NodePtr>( + [](auto&& list) { + return ast::make_node_ptr<ast::ExecutionListNode>(ast::ExecutionNode::Type::Trigger, LEXY_MOV(list)); + }); + }; + + struct TriggerBlock { + static constexpr auto rule = lexy::dsl::curly_bracketed.opt(lexy::dsl::p<TriggerList>); + + static constexpr auto value = lexy::forward<ast::NodePtr>; }; }
\ No newline at end of file |