2
2
3
3
#include < string_view>
4
4
#include < optional>
5
+ #include < vector>
5
6
#include < lexy/dsl.hpp>
6
7
#include < lexy/callback.hpp>
7
8
#include " ecsact/parse/status.h"
@@ -65,6 +66,106 @@ struct whitespace {
65
66
lexy::dsl::inline_<line_comment> | lexy::dsl::inline_<block_comment>;
66
67
};
67
68
69
+ struct parameter_name {
70
+ static constexpr auto rule = lexy::dsl::
71
+ identifier (lexy::dsl::ascii::alpha, lexy::dsl::ascii::alnum / lexy::dsl::lit_c<' _' >);
72
+
73
+ static constexpr auto value = lexy::as_string<std::string_view>;
74
+ };
75
+
76
+ struct parameter_value {
77
+ struct invalid_value_syntax {
78
+ static constexpr auto name = " Invalid parameter value syntax" ;
79
+ };
80
+
81
+ struct number {
82
+ static constexpr auto rule = [] {
83
+ using namespace lexy ;
84
+ auto digits = dsl::digits<>.sep (dsl::digit_sep_tick).no_leading_zero ();
85
+ return dsl::integer<int32_t >(digits);
86
+ }();
87
+
88
+ static constexpr auto value = lexy::as_integer<int32_t >;
89
+ };
90
+
91
+ struct boolean {
92
+ struct true_keyword : lexy::transparent_production {
93
+ static constexpr auto rule = LEXY_LIT(" true" );
94
+ static constexpr auto value = lexy::constant(true );
95
+ };
96
+
97
+ struct false_keyword : lexy::transparent_production {
98
+ static constexpr auto rule = LEXY_LIT(" false" );
99
+ static constexpr auto value = lexy::constant(false );
100
+ };
101
+
102
+ static constexpr auto rule = lexy::dsl::p<true_keyword> |
103
+ lexy::dsl::p<false_keyword>;
104
+
105
+ static constexpr auto value = lexy::forward<bool >;
106
+ };
107
+
108
+ static constexpr auto rule = lexy::dsl::p<number> | lexy::dsl::p<boolean>;
109
+
110
+ using value_variant = std::variant<bool , int32_t >;
111
+
112
+ static constexpr auto value = lexy::callback<value_variant>(
113
+ [](auto && value) -> value_variant { return value_variant{value}; }
114
+ );
115
+ };
116
+
117
+ struct parameter {
118
+ using value_variant = typename parameter_value::value_variant;
119
+
120
+ static void _set_value (ecsact_statement_parameter& param, int32_t value) {
121
+ param.value .type = ECSACT_STATEMENT_PARAM_VALUE_TYPE_INTEGER;
122
+ param.value .data .integer_value = value;
123
+ }
124
+
125
+ static void _set_value (ecsact_statement_parameter& param, bool value) {
126
+ param.value .type = ECSACT_STATEMENT_PARAM_VALUE_TYPE_BOOL;
127
+ param.value .data .bool_value = value;
128
+ }
129
+
130
+ static constexpr auto rule = lexy::dsl::p<parameter_name> >>
131
+ lexy::dsl::opt (lexy::dsl::lit_c<' :' > >> lexy::dsl::p<parameter_value>);
132
+
133
+ static constexpr auto value = lexy::callback<ecsact_statement_parameter>(
134
+ [](std::string_view param_name, std::optional<value_variant> param_value) {
135
+ auto result = ecsact_statement_parameter{};
136
+ result.name = ecsact_statement_sv{
137
+ .data = param_name.data (),
138
+ .length = static_cast <int32_t >(param_name.size ()),
139
+ };
140
+
141
+ if (param_value) {
142
+ std::visit (
143
+ [&](auto && param_value) {
144
+ parameter::_set_value (result, param_value);
145
+ },
146
+ *param_value
147
+ );
148
+ } else {
149
+ parameter::_set_value (result, true );
150
+ }
151
+
152
+ return result;
153
+ }
154
+ );
155
+ };
156
+
157
+ struct parameters {
158
+ static constexpr auto rule = [] {
159
+ return lexy::dsl::parenthesized.list (
160
+ lexy::dsl::p<parameter>,
161
+ lexy::dsl::sep (lexy::dsl::comma)
162
+ );
163
+ }();
164
+
165
+ static constexpr auto value =
166
+ lexy::as_list<std::vector<ecsact_statement_parameter>>;
167
+ };
168
+
68
169
/* *
69
170
* Lookupable type name
70
171
*/
@@ -690,6 +791,26 @@ struct control {
690
791
struct statement_value {
691
792
ecsact_statement statement;
692
793
ecsact_parse_status_code status;
794
+
795
+ /* *
796
+ * Temporary parameters that will be added to `statement`.
797
+ * SEE: collect_parameters
798
+ */
799
+ std::optional<std::vector<ecsact_statement_parameter>> _parameters;
800
+
801
+ auto collect_parameters () {
802
+ if (_parameters) {
803
+ auto parameters = *_parameters;
804
+ statement.parameters_length = static_cast <int32_t >(parameters.size ());
805
+ for (int i = 0 ; statement.parameters_length > i; ++i) {
806
+ statement.parameters [i] = parameters[i];
807
+ }
808
+
809
+ _parameters = std::nullopt;
810
+ } else {
811
+ statement.parameters_length = 0 ;
812
+ }
813
+ }
693
814
};
694
815
695
816
template <
@@ -716,10 +837,13 @@ struct statement {
716
837
717
838
auto statement =
718
839
(lexyd::member<& statement_value::statement> = statement_p);
840
+ auto statement_params =
841
+ (lexyd::member<& statement_value::_parameters> =
842
+ lexy::dsl::opt (lexyd::p<parameters>));
719
843
auto status =
720
844
(lexyd::member<& statement_value::status> = lexyd::p<parse_end>);
721
845
722
- return statement + status;
846
+ return statement + statement_params + status;
723
847
}();
724
848
725
849
static constexpr auto value = lexy::as_aggregate<statement_value>;
0 commit comments