7#include "formula_node.hpp"
8#include "formula_add_node.hpp"
9#include "formula_arguments.hpp"
10#include "formula_assign_node.hpp"
11#include "formula_binary_operator_node.hpp"
12#include "formula_bit_and_node.hpp"
13#include "formula_bit_or_node.hpp"
14#include "formula_bit_xor_node.hpp"
15#include "formula_call_node.hpp"
16#include "formula_decrement_node.hpp"
17#include "formula_div_node.hpp"
18#include "formula_eq_node.hpp"
19#include "formula_evaluation_context.hpp"
20#include "formula_filter_node.hpp"
21#include "formula_ge_node.hpp"
22#include "formula_gt_node.hpp"
23#include "formula_increment_node.hpp"
24#include "formula_index_node.hpp"
25#include "formula_inplace_add_node.hpp"
26#include "formula_inplace_and_node.hpp"
27#include "formula_inplace_div_node.hpp"
28#include "formula_inplace_mod_node.hpp"
29#include "formula_inplace_mul_node.hpp"
30#include "formula_inplace_or_node.hpp"
31#include "formula_inplace_shl_node.hpp"
32#include "formula_inplace_shr_node.hpp"
33#include "formula_inplace_sub_node.hpp"
34#include "formula_inplace_xor_node.hpp"
35#include "formula_invert_node.hpp"
36#include "formula_le_node.hpp"
37#include "formula_literal_node.hpp"
38#include "formula_logical_and_node.hpp"
39#include "formula_logical_not_node.hpp"
40#include "formula_logical_or_node.hpp"
41#include "formula_lt_node.hpp"
42#include "formula_map_literal_node.hpp"
43#include "formula_member_node.hpp"
44#include "formula_minus_node.hpp"
45#include "formula_mod_node.hpp"
46#include "formula_mul_node.hpp"
47#include "formula_name_node.hpp"
48#include "formula_ne_node.hpp"
49#include "formula_plus_node.hpp"
50#include "formula_pow_node.hpp"
51#include "formula_shl_node.hpp"
52#include "formula_shr_node.hpp"
53#include "formula_sub_node.hpp"
54#include "formula_ternary_operator_node.hpp"
55#include "formula_unary_operator_node.hpp"
56#include "formula_vector_literal_node.hpp"
57#include "formula_post_process_context.hpp"
58#include "../macros.hpp"
63hi_export_module(hikogui.formula.formula_parser);
65hi_export
namespace hi {
inline namespace v1 {
67template<std::input_iterator It, std::sentinel_for<It> ItEnd>
70template<std::input_iterator It, std::sentinel_for<It> ItEnd>
75 if (
op != token::other) {
76 return {uint8_t{0},
false};
89 case operator_to_int(
"."):
91 case operator_to_int(
"**"):
93 case operator_to_int(
"*"):
95 case operator_to_int(
"/"):
97 case operator_to_int(
"%"):
99 case operator_to_int(
"+"):
101 case operator_to_int(
"-"):
103 case operator_to_int(
"<<"):
105 case operator_to_int(
">>"):
107 case operator_to_int(
"<"):
109 case operator_to_int(
">"):
111 case operator_to_int(
"<="):
113 case operator_to_int(
">="):
115 case operator_to_int(
"=="):
117 case operator_to_int(
"!="):
119 case operator_to_int(
"&"):
121 case operator_to_int(
"^"):
123 case operator_to_int(
"|"):
125 case operator_to_int(
"&&"):
127 case operator_to_int(
"||"):
129 case operator_to_int(
"?"):
131 case operator_to_int(
"["):
133 case operator_to_int(
"("):
135 case operator_to_int(
"="):
137 case operator_to_int(
"+="):
139 case operator_to_int(
"-="):
141 case operator_to_int(
"*="):
143 case operator_to_int(
"/="):
145 case operator_to_int(
"%="):
147 case operator_to_int(
"<<="):
149 case operator_to_int(
">>="):
151 case operator_to_int(
"&="):
153 case operator_to_int(
"|="):
155 case operator_to_int(
"^="):
157 case operator_to_int(
"!"):
160 throw parse_error(std::format(
"{}: Unexpected binary operator {}.",
op.line_nr,
op.column_nr,
op));
165 case operator_to_int(
"+"):
167 case operator_to_int(
"-"):
169 case operator_to_int(
"~"):
171 case operator_to_int(
"!"):
173 case operator_to_int(
"++"):
175 case operator_to_int(
"--"):
178 throw parse_error(std::format(
"{}:{}: Unexpected unary operator {}.",
op.line_nr,
op.column_nr,
op));
192template<std::input_iterator It, std::sentinel_for<It> ItEnd>
195 hi_assert(
it != last);
196 hilet line_nr =
it->line_nr;
197 hilet column_nr =
it->column_nr;
199 if (*
it == token::integer) {
200 return std::make_unique<formula_literal_node>(line_nr, column_nr,
datum{
static_cast<long long>(*
it++)});
202 }
else if (*
it == token::real) {
203 return std::make_unique<formula_literal_node>(line_nr, column_nr,
datum{
static_cast<double>(*
it++)});
205 }
else if (*
it == token::dstr) {
206 return std::make_unique<formula_literal_node>(line_nr, column_nr,
datum{
static_cast<std::string>(*
it++)});
208 }
else if (*
it == token::id
and *
it ==
"true") {
210 return std::make_unique<formula_literal_node>(line_nr, column_nr,
datum{
true});
212 }
else if (*
it == token::id
and *
it ==
"false") {
214 return std::make_unique<formula_literal_node>(line_nr, column_nr,
datum{
false});
216 }
else if (*
it == token::id
and *
it ==
"null") {
218 return std::make_unique<formula_literal_node>(line_nr, column_nr,
datum{
nullptr});
220 }
else if (*
it == token::id
and *
it ==
"undefined") {
222 return std::make_unique<formula_literal_node>(line_nr, column_nr,
datum{});
224 }
else if (*
it == token::id) {
225 return std::make_unique<formula_name_node>(line_nr, column_nr,
static_cast<std::string>(*
it++));
227 }
else if (*
it ==
'(') {
234 throw parse_error(std::format(
"{}:{}: Expected ')' token for function call got {}.", line_nr, column_nr, *
it));
239 }
else if (*
it ==
'[') {
242 formula_node::formula_vector values;
250 }
else if (*
it ==
']') {
255 std::format(
"{}:{}: Expected ']' or ',' after a vector sub-formula. got {}", line_nr, column_nr, *
it));
259 return std::make_unique<formula_vector_literal_node>(line_nr, column_nr,
std::move(values));
261 }
else if (*
it ==
'{') {
264 formula_node::formula_vector keys;
265 formula_node::formula_vector values;
274 throw parse_error(std::format(
"{}:{}: Expected ':' after a map key. got {}", line_nr, column_nr, *
it));
281 }
else if (*
it ==
'}') {
286 std::format(
"{}:{}: Expected ']' or ',' after a vector sub-formula. got {}.", line_nr, column_nr, *
it));
290 return std::make_unique<formula_map_literal_node>(line_nr, column_nr,
std::move(keys),
std::move(values));
292 }
else if (*
it == token::other) {
300 throw parse_error(std::format(
"{}:{}: Unexpected token in primary formula {}.", line_nr, column_nr, *
it));
306template<std::input_iterator It, std::sentinel_for<It> ItEnd>
309 hi_assert(
it != last);
316 throw parse_error(std::format(
"{}:{}: Expected ']' token at end of indexing operator got {}.",
it->line_nr,
it->column_nr, *
it));
323template<std::input_iterator It, std::sentinel_for<It> ItEnd>
326 hi_assert(
it != last);
333 throw parse_error(std::format(
"{}:{}: Expected ':' token in ternary formula {}.",
it->line_nr,
it->column_nr, *
it));
338 return std::make_unique<formula_arguments>(
it->line_nr,
it->column_nr,
std::move(rhs_true),
std::move(rhs_false));
343template<std::input_iterator It, std::sentinel_for<It> ItEnd>
346 hi_assert(
it != last);
348 formula_node::formula_vector args;
361 }
else if (*
it ==
')') {
367 std::format(
"{}:{}: Expected ',' or ')' After a function argument {}.",
it->line_nr,
it->column_nr, *
it));
371 return std::make_unique<formula_arguments>(
it->line_nr,
it->column_nr,
std::move(args));
374template<std::input_iterator It, std::sentinel_for<It> ItEnd>
375[[
nodiscard]]
bool parse_formula_is_at_end(
It&
it, ItEnd last)
381 if (*
it != token::other) {
382 throw parse_error(std::format(
"{}:{}: Expecting an operator token got {}.",
it->line_nr,
it->column_nr, *
it));
392template<std::input_iterator It, std::sentinel_for<It> ItEnd>
400 if (parse_formula_is_at_end(
it, last)) {
412 }
else if (
op ==
'(') {
414 }
else if (
op ==
'?') {
421 if (parse_formula_is_at_end(
it, last)) {
430 if (parse_formula_is_at_end(
it, last)) {
443template<std::input_iterator It, std::sentinel_for<It> ItEnd>
455 auto token_it = lexer<lexer_config::c_style()>.parse(text.begin(), text.end());
465 e->post_process(post_process_context);
477 std::string_view::const_iterator first,
478 std::string_view::const_iterator last,
485 for (
auto i = first; i != last; i++) {
492 }
else if (*i ==
'\\') {
DOXYGEN BUG.
Definition algorithm.hpp:16
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
std::unique_ptr< formula_node > parse_index_formula(It &it, ItEnd last)
Parse the rhs of an index operator, including the closing bracket.
Definition formula_parser.hpp:307
std::unique_ptr< formula_node > parse_ternary_argument_formula(It &it, ItEnd last)
Parse the rhs of an index operator, including the closing bracket.
Definition formula_parser.hpp:324
std::unique_ptr< formula_node > parse_formula_1(It &it, ItEnd last, std::unique_ptr< formula_node > lhs, uint8_t min_precedence)
Parse an formula.
Definition formula_parser.hpp:393
std::unique_ptr< formula_node > parse_call_argument_formula(It &it, ItEnd last)
Parse the rhs of an index operator, including the closing bracket.
Definition formula_parser.hpp:344
constexpr std::string_view::const_iterator find_end_of_formula(std::string_view::const_iterator first, std::string_view::const_iterator last, std::string_view terminating_string) noexcept
Find the end of an formula.
Definition formula_parser.hpp:476
std::unique_ptr< formula_node > parse_primary_formula(It &it, ItEnd last)
Parse a lhs or rhs part of an formula.
Definition formula_parser.hpp:193
std::unique_ptr< formula_node > parse_formula_without_post_processing(std::string_view text)
Parse an formula.
Definition formula_parser.hpp:453
std::unique_ptr< formula_node > parse_formula(It &it, ItEnd last)
Parse an formula.
Definition formula_parser.hpp:444
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
A dynamic data type.
Definition datum.hpp:212
Definition formula_post_process_context.hpp:237
Exception thrown during parsing on an error.
Definition exception_intf.hpp:47