-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmath_expr_grammar.h
More file actions
133 lines (115 loc) · 6.26 KB
/
Copy pathmath_expr_grammar.h
File metadata and controls
133 lines (115 loc) · 6.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#pragma once
#include "cura-formulae-engine/ast/binary_expr/add_expr.h"
#include "cura-formulae-engine/ast/binary_expr/and_expr.h"
#include "cura-formulae-engine/ast/binary_expr/div_expr.h"
#include "cura-formulae-engine/ast/binary_expr/mod_expr.h"
#include "cura-formulae-engine/ast/binary_expr/mul_expr.h"
#include "cura-formulae-engine/ast/binary_expr/or_expr.h"
#include "cura-formulae-engine/ast/binary_expr/pow_expr.h"
#include "cura-formulae-engine/ast/binary_expr/sub_expr.h"
#include "cura-formulae-engine/ast/comp_chain_expr.h"
#include "cura-formulae-engine/ast/expr_ptr.h"
#include "cura-formulae-engine/ast/unary_expr/neg_expr.h"
#include "cura-formulae-engine/ast/unary_expr/not_expr.h"
#include "variable_or_fn_application_grammar_or_array_indexing_grammar.h"
#include <lexy/callback/adapter.hpp>
#include <lexy/callback/fold.hpp>
#include <lexy/callback/forward.hpp>
#include <memory>
#include <utility>
namespace CuraFormulaeEngine::parser
{
struct MathExprGrammar : lexy::expression_production
{
static constexpr auto whitespace = lexy::dsl::ascii::space;
// clang-format off
static constexpr auto atom
= lexy::dsl::p<VariableOrFnApplicationGrammarOrArrayIndexingGrammar>;
// clang-format on
static constexpr auto op_pow = lexy::dsl::op(LEXY_LIT("**"));
struct number_power : lexy::dsl::infix_op_right
{
static constexpr auto op = op_pow;
using operand = lexy::dsl::atom;
};
static constexpr auto op_neg = lexy::dsl::op(LEXY_LIT("-"));
struct number_prefix : lexy::dsl::prefix_op
{
static constexpr auto op = op_neg;
using operand = number_power;
};
static constexpr auto op_mul = lexy::dsl::op(LEXY_LIT("*"));
static constexpr auto op_div = lexy::dsl::op(LEXY_LIT("/"));
static constexpr auto op_mod = lexy::dsl::op(LEXY_LIT("%"));
struct number_product : lexy::dsl::infix_op_left
{
using operand = number_prefix;
static constexpr auto op = op_mul / op_div / op_mod;
};
static constexpr auto op_add = lexy::dsl::op(LEXY_LIT("+"));
static constexpr auto op_sub = lexy::dsl::op(LEXY_LIT("-"));
struct number_sum : lexy::dsl::infix_op_left
{
using operand = number_product;
static constexpr auto op = op_add / op_sub;
};
static constexpr auto op_eq = lexy::dsl::op(LEXY_LIT("=="));
static constexpr auto op_neq = lexy::dsl::op(LEXY_LIT("!="));
static constexpr auto op_lt = lexy::dsl::op(LEXY_LIT("<"));
static constexpr auto op_gt = lexy::dsl::op(LEXY_LIT(">"));
static constexpr auto op_leq = lexy::dsl::op(LEXY_LIT("<="));
static constexpr auto op_geq = lexy::dsl::op(LEXY_LIT(">="));
static constexpr auto op_not_member = lexy::dsl::op(LEXY_LIT("not in"));
static constexpr auto op_member = lexy::dsl::op(LEXY_LIT("in"));
struct number_compare : lexy::dsl::infix_op_list
{
using operand = number_sum;
static constexpr auto op = op_eq / op_neq / op_lt / op_gt / op_leq / op_geq / op_not_member / op_member;
};
static constexpr auto op_not = lexy::dsl::op(LEXY_LIT("not"));
struct bool_prefix : lexy::dsl::prefix_op
{
static constexpr auto op = op_not;
using operand = number_compare;
};
static constexpr auto op_and = lexy::dsl::op(LEXY_LIT("and"));
struct bool_and : lexy::dsl::infix_op_left
{
static constexpr auto op = op_and;
using operand = bool_prefix;
};
static constexpr auto op_or = lexy::dsl::op(LEXY_LIT("or"));
struct bool_or : lexy::dsl::infix_op_left
{
static constexpr auto op = op_or;
using operand = bool_and;
};
using operation = bool_or;
// clang-format off
static constexpr auto value = lexy::fold_inplace<std::unique_ptr<CuraFormulaeEngine::ast::ComparisonChainExpr>>(
[] { return std::make_unique<CuraFormulaeEngine::ast::ComparisonChainExpr>(); },
[](auto&& node, lexy::op<op_eq>) { node->operators.emplace_back(CuraFormulaeEngine::ast::ComparisonOperators::Equals); },
[](auto&& node, lexy::op<op_neq>) { node->operators.emplace_back(CuraFormulaeEngine::ast::ComparisonOperators::NotEquals); },
[](auto&& node, lexy::op<op_lt>) { node->operators.emplace_back(CuraFormulaeEngine::ast::ComparisonOperators::LessThan); },
[](auto&& node, lexy::op<op_gt>) { node->operators.emplace_back(CuraFormulaeEngine::ast::ComparisonOperators::GreaterThan); },
[](auto&& node, lexy::op<op_leq>) { node->operators.emplace_back(CuraFormulaeEngine::ast::ComparisonOperators::LessThenEqual); },
[](auto&& node, lexy::op<op_geq>) { node->operators.emplace_back(CuraFormulaeEngine::ast::ComparisonOperators::GreaterThenEqual); },
[](auto&& node, lexy::op<op_not_member>) { node->operators.emplace_back(CuraFormulaeEngine::ast::ComparisonOperators::NotMember); },
[](auto&& node, lexy::op<op_member>) { node->operators.emplace_back(CuraFormulaeEngine::ast::ComparisonOperators::Member); },
[](auto&& node, ast::ExprPtr&& expr) { node->expressions.emplace_back(std::move(expr)); }
) >> lexy::callback<ast::ExprPtr>(
lexy::forward<ast::ExprPtr>,
[](lexy::op<op_neg>, ast::ExprPtr&& operand) { return - std::move(operand); },
[](lexy::op<op_not>, ast::ExprPtr&& operand) { return ! std::move(operand); },
[](ast::ExprPtr&& lhs, lexy::op<op_pow>, ast::ExprPtr&& rhs) { return ast::ExprPtr(std::make_unique<ast::PowExpr>(std::move(lhs), std::move(rhs))); },
[](ast::ExprPtr&& lhs, lexy::op<op_mul>, ast::ExprPtr&& rhs) { return std::move(lhs) * std::move(rhs); },
[](ast::ExprPtr&& lhs, lexy::op<op_div>, ast::ExprPtr&& rhs) { return std::move(lhs) / std::move(rhs); },
[](ast::ExprPtr&& lhs, lexy::op<op_mod>, ast::ExprPtr&& rhs) { return std::move(lhs) % std::move(rhs); },
[](ast::ExprPtr&& lhs, lexy::op<op_add>, ast::ExprPtr&& rhs) { return std::move(lhs) + std::move(rhs); },
[](ast::ExprPtr&& lhs, lexy::op<op_sub>, ast::ExprPtr&& rhs) { return std::move(lhs) - std::move(rhs); },
[](ast::ExprPtr&& lhs, lexy::op<op_and>, ast::ExprPtr&& rhs) { return std::move(lhs) && std::move(rhs); },
[](ast::ExprPtr&& lhs, lexy::op<op_or>, ast::ExprPtr&& rhs) { return std::move(lhs) || std::move(rhs); }
);
// clang-format on
};
} // namespace CuraFormulaeEngine::parser