9namespace client {
namespace parser
11 template <
typename Iterator>
18 template <
typename Iterator>
22 if (std::isspace(
static_cast<unsigned char>(*it))) {
24 }
else if (*it ==
'/' && std::next(it) != last && *std::next(it) ==
'*') {
26 while (it != last && !(*it ==
'*' && std::next(it) != last && *std::next(it) ==
'/')) {
38 template <
typename Iterator>
42 if (it != last && *it == c) {
49 template <
typename Iterator>
54 char const* w = token;
55 while (*w !=
'\0' && cur != last && *cur == *w) {
66 template <
typename Iterator>
72 while (*w !=
'\0' && cur != last && *cur == *w) {
79 if (cur != last && (std::isalnum(
static_cast<unsigned char>(*cur)) || *cur ==
'_')) {
86 template <
typename Iterator>
91 if (it == last || !(std::isalpha(
static_cast<unsigned char>(*it)) || *it ==
'_')) {
96 while (cur != last && (std::isalnum(
static_cast<unsigned char>(*cur)) || *cur ==
'_')) {
99 std::string token(save, cur);
100 if (token ==
"true" || token ==
"false") {
104 word = std::move(token);
108 template <
typename Iterator>
115 if (e.rest.empty()) {
116 return std::move(e.first);
125 template <
typename Iterator>
126 template <
typename NextLevel,
typename OpMatcher>
129 NextLevel next, OpMatcher match_op)
134 if (!next(it, last, firstExpr)) {
139 out.
first = to_operand(std::move(firstExpr));
144 std::optional<ast::optoken> op = match_op(it, last);
151 if (!next(it, last, rhsExpr)) {
152 error_handler_(std::string(
"Error! "), std::string(
"Expecting operand"), it);
158 to_operand(std::move(rhsExpr))
160 out.
rest.push_back(std::move(operation));
166 template <
typename Iterator>
169 return parse_level(it, last, out,
170 [
this](Iterator& i, Iterator l,
ast::expression& o) {
return parse_logical_and(i, l, o); },
171 [
this](Iterator& i, Iterator l) -> std::optional<ast::optoken> {
172 if (match_op_token(i, l,
"||"))
return ast::op_or;
177 template <
typename Iterator>
180 return parse_level(it, last, out,
181 [
this](Iterator& i, Iterator l,
ast::expression& o) {
return parse_equality(i, l, o); },
182 [
this](Iterator& i, Iterator l) -> std::optional<ast::optoken> {
183 if (match_op_token(i, l,
"&&"))
return ast::op_and;
188 template <
typename Iterator>
191 return parse_level(it, last, out,
192 [
this](Iterator& i, Iterator l,
ast::expression& o) {
return parse_relational(i, l, o); },
193 [
this](Iterator& i, Iterator l) -> std::optional<ast::optoken> {
200 template <
typename Iterator>
203 return parse_level(it, last, out,
204 [
this](Iterator& i, Iterator l,
ast::expression& o) {
return parse_additive(i, l, o); },
205 [
this](Iterator& i, Iterator l) -> std::optional<ast::optoken> {
214 template <
typename Iterator>
217 return parse_level(it, last, out,
218 [
this](Iterator& i, Iterator l,
ast::expression& o) {
return parse_multiplicative(i, l, o); },
219 [
this](Iterator& i, Iterator l) -> std::optional<ast::optoken> {
226 template <
typename Iterator>
229 return parse_level(it, last, out,
232 if (!parse_unary(i, l, operand))
return false;
233 o.
first = std::move(operand);
237 [
this](Iterator& i, Iterator l) -> std::optional<ast::optoken> {
244 template <
typename Iterator>
250 if (match(it, last,
'+')) {
252 }
else if (match(it, last,
'-')) {
254 }
else if (match(it, last,
'!')) {
261 return parse_primary(it, last, out);
265 if (!parse_unary(it, last, sub)) {
277 template <
typename Iterator>
284 bool hasDigits =
false;
285 while (cur != last && std::isdigit(
static_cast<unsigned char>(*cur))) {
289 if (cur != last && *cur ==
'.') {
290 Iterator afterDot = cur;
292 if (afterDot != last && std::isdigit(
static_cast<unsigned char>(*afterDot))) {
294 while (cur != last && std::isdigit(
static_cast<unsigned char>(*cur))) {
298 }
else if (hasDigits) {
305 if (cur != last && (*cur ==
'e' || *cur ==
'E')) {
306 Iterator expIt = cur;
308 if (expIt != last && (*expIt ==
'+' || *expIt ==
'-')) {
311 if (expIt != last && std::isdigit(
static_cast<unsigned char>(*expIt))) {
312 while (expIt != last && std::isdigit(
static_cast<unsigned char>(*expIt))) {
319 std::string token(save, cur);
321 double value = std::strtod(token.c_str(), &
end);
322 if (
end != token.c_str() + token.size()) {
331 template <
typename Iterator>
334 if (parse_constant(it, last, out)) {
340 if (try_identifier_token(it, last, word)) {
341 Iterator afterWord = it;
342 if (match(it, last,
'(')) {
345 std::list<ast::function_call_argument> args;
346 if (!parse_argument_list(it, last, args)) {
349 fc.
args = std::move(args);
350 if (!match(it, last,
')')) {
351 error_handler_(std::string(
"Error! "), std::string(
"Expecting \")\""), it);
355 annotation_(out, save);
362 annotation_(out, save);
367 if (match_word(it, last,
"true")) {
369 annotation_(out, save);
372 if (match_word(it, last,
"false")) {
374 annotation_(out, save);
378 if (match(it, last,
'(')) {
380 if (!parse_expr(it, last, e)) {
383 if (!match(it, last,
')')) {
384 error_handler_(std::string(
"Error! "), std::string(
"Expecting \")\""), it);
387 out = to_operand(std::move(e));
388 annotation_(out, save);
396 template <
typename Iterator>
402 if (parse_expr(it, last, e)) {
409 if (parse_quoted_string(it, last, s)) {
418 template <
typename Iterator>
424 if (!parse_call_argument(it, last, firstArg)) {
427 out.push_back(std::move(firstArg));
430 Iterator commaPos = it;
431 if (!match(it, last,
',')) {
437 if (!parse_call_argument(it, last,
arg)) {
438 error_handler_(std::string(
"Error! "), std::string(
"Expecting argument"), it);
441 out.push_back(std::move(
arg));
447 template <
typename Iterator>
451 if (it == last || (*it !=
'\'' && *it !=
'"')) {
459 while (cur != last && *cur != quote) {
468 out = std::move(value);
472 template <
typename Iterator>
475 return parse_logical_or(it, last, out);
478 template <
typename Iterator>
482 if (!parse_expr(it, last, attr)) {
483 error_handler_(std::string(
"Error! "), std::string(
"Expecting expression"), it);
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
std::variant< expression, quoted_string > function_call_argument
std::variant< nil, bool, unsigned int, double, identifier, recursive_wrapper< unary >, recursive_wrapper< function_call >, recursive_wrapper< expression > > operand
std::list< function_call_argument > args
std::list< operation > rest
bool parse_logical_and(Iterator &it, Iterator last, ast::expression &out)
bool parse_primary(Iterator &it, Iterator last, ast::operand &out)
bool parse_multiplicative(Iterator &it, Iterator last, ast::expression &out)
bool parse_argument_list(Iterator &it, Iterator last, std::list< ast::function_call_argument > &out)
bool parse_quoted_string(Iterator &it, Iterator last, std::string &out)
bool parse_call_argument(Iterator &it, Iterator last, ast::function_call_argument &out)
expression(error_handler< Iterator > &error_handler)
bool match_word(Iterator &it, Iterator last, char const *word) const
bool parse_constant(Iterator &it, Iterator last, ast::operand &out)
bool parse_relational(Iterator &it, Iterator last, ast::expression &out)
bool parse_level(Iterator &it, Iterator last, ast::expression &out, NextLevel next, OpMatcher match_op)
bool match_op_token(Iterator &it, Iterator last, char const *token) const
bool parse(Iterator &first, Iterator last, ast::expression &attr)
bool parse_expr(Iterator &it, Iterator last, ast::expression &out)
static ast::operand to_operand(ast::expression &&e)
void skip_ws(Iterator &it, Iterator last) const
bool parse_logical_or(Iterator &it, Iterator last, ast::expression &out)
bool parse_unary(Iterator &it, Iterator last, ast::operand &out)
bool parse_equality(Iterator &it, Iterator last, ast::expression &out)
bool try_identifier_token(Iterator &it, Iterator last, std::string &word) const
bool match(Iterator &it, Iterator last, char c) const
bool parse_additive(Iterator &it, Iterator last, ast::expression &out)