4#include "Expression.hpp"
6#include <State/AddressParser.hpp>
7#include <State/ValueParser.hpp>
60BOOST_FUSION_ADAPT_STRUCT(
62 (State::RelationMember,
63 lhs)(ossia::expressions::comparator, op)(State::RelationMember, rhs))
68namespace qi = boost::spirit::qi;
70using boost::spirit::qi::rule;
73template <
typename Iterator>
74struct RelationMember_parser : qi::grammar<Iterator, State::RelationMember()>
76 RelationMember_parser()
77 : RelationMember_parser::base_type(start)
79 start %= (
"%" >> addracc >>
"%") | (
"%" >> addr >>
"%") | val;
82 Address_parser<Iterator> addr;
83 AddressAccessor_parser<Iterator> addracc;
84 Value_parser<Iterator> val;
85 qi::rule<
Iterator, State::RelationMember()> start;
89struct RelationOperation_map : qi::symbols<char, ossia::expressions::comparator>
91 RelationOperation_map()
93 add(
"<=", ossia::expressions::comparator::LOWER_EQUAL)(
94 ">=", ossia::expressions::comparator::GREATER_EQUAL)(
95 "<", ossia::expressions::comparator::LOWER)(
96 ">", ossia::expressions::comparator::GREATER)(
97 "!=", ossia::expressions::comparator::DIFFERENT)(
98 "==", ossia::expressions::comparator::EQUAL)(
99 "contains", ossia::expressions::comparator::CONTAINS);
103template <
typename Iterator>
104struct Relation_parser : qi::grammar<Iterator, State::Relation()>
107 : Relation_parser::base_type(start)
109 using boost::spirit::qi::skip;
110 start %= skip(boost::spirit::standard::space)[(rm_parser >> op_map >> rm2_parser)];
113 RelationMember_parser<Iterator> rm_parser;
114 RelationMember_parser<Iterator> rm2_parser;
115 RelationOperation_map op_map;
119template <
typename Iterator>
120struct Pulse_parser : qi::grammar<Iterator, State::Pulse()>
123 : Pulse_parser::base_type(start)
125 using boost::spirit::qi::lit;
126 using boost::spirit::qi::skip;
127 using boost::spirit::standard::string;
128 start %= skip(boost::spirit::standard::space)[
"%" >> addr >>
"%" >>
"impulse"]
129 | skip(boost::spirit::standard::space)
130 [lit(
'{') >> lit(
"%") >> addr >> lit(
"%") >> lit(
"impulse") >>
'}'];
133 Address_parser<Iterator> addr;
139namespace qi = boost::spirit::qi;
154typedef std::string var;
155template <
typename tag>
157template <
typename tag>
160using expr_raw = boost::variant<
162 boost::recursive_wrapper<binop<op_and>>, boost::recursive_wrapper<binop<op_xor>>,
163 boost::recursive_wrapper<binop<op_or>>>;
165template <
typename tag>
168 explicit binop(expr_raw l, expr_raw r)
169 : oper1(
std::move(l))
170 , oper2(
std::move(r))
173 expr_raw oper1, oper2;
176template <
typename tag>
179 explicit unop(expr_raw o)
180 : oper1(
std::move(o))
186template <
typename Op>
187struct ExpressionOpConstruct
190 boost::fusion::vector<expr_raw, expr_raw> x,
auto& context,
191 qi::unused_type)
const noexcept
193 boost::fusion::at_c<0>(context.attributes)
194 = binop<Op>(boost::fusion::at_c<0>(x), boost::fusion::at_c<1>(x));
196 void operator()(expr_raw x,
auto& context, qi::unused_type)
const noexcept
198 boost::fusion::at_c<0>(context.attributes) = unop<Op>(x);
202struct ExpressionOpIdent
204 void operator()(expr_raw x,
auto& context, qi::unused_type)
const noexcept
206 boost::fusion::at_c<0>(context.attributes) = x;
209template <
typename It,
typename Skipper = qi::space_type>
210struct Expression_parser : qi::grammar<It, expr_raw(), Skipper>
213 : Expression_parser::base_type(expr_)
219 namespace bsi = boost::spirit;
220 or_ = (xor_ >>
"or" >> or_)[ExpressionOpConstruct<op_or>{}]
221 | xor_[ExpressionOpIdent{}];
222 xor_ = (and_ >>
"xor" >> xor_)[ExpressionOpConstruct<op_xor>{}]
223 | and_[ExpressionOpIdent{}];
224 and_ = (not_ >>
"and" >> and_)[ExpressionOpConstruct<op_and>{}]
225 | not_[ExpressionOpIdent{}];
226 not_ = (
"not" > simple)[ExpressionOpConstruct<op_not>{}]
227 | simple[ExpressionOpIdent{}];
229 simple = ((
'{' >> expr_ >>
'}') | relation_ | pulse_);
233 Relation_parser<It> relation_;
234 Pulse_parser<It> pulse_;
235 qi::rule<It, expr_raw(), Skipper> not_, and_, xor_, or_, simple, expr_;
238struct Expression_builder : boost::static_visitor<void>
246 void operator()(
const State::Relation& rel) { m_current->emplace_back(rel,
nullptr); }
248 void operator()(
const State::Pulse& rel) { m_current->emplace_back(rel,
nullptr); }
250 void operator()(
const binop<op_and>& b)
252 rec_binop(State::BinaryOperator::AND, b.oper1, b.oper2);
254 void operator()(
const binop<op_or>& b)
256 rec_binop(State::BinaryOperator::OR, b.oper1, b.oper2);
258 void operator()(
const binop<op_xor>& b)
260 rec_binop(State::BinaryOperator::XOR, b.oper1, b.oper2);
263 void rec_binop(State::BinaryOperator binop,
const expr_raw& l,
const expr_raw& r)
265 m_current->emplace_back(binop,
nullptr);
267 auto old_expr = m_current;
268 m_current = &old_expr->children().back();
270 boost::apply_visitor(*
this, l);
271 boost::apply_visitor(*
this, r);
273 m_current = old_expr;
276 void operator()(
const unop<op_not>& u)
278 m_current->emplace_back(State::UnaryOperator::Not,
nullptr);
280 auto old_expr = m_current;
281 m_current = &old_expr->children().back();
283 boost::apply_visitor(*
this, u.oper1);
285 m_current = old_expr;
290std::optional<State::Expression> State::parseExpression(
const std::string& input)
292 auto f(std::begin(input)), l(std::end(input));
293 auto p = std::make_unique<Expression_parser<
decltype(f)>>();
297 bool ok = qi::phrase_parse(f, l, *p, qi::standard::space, result);
306 Expression_builder bldr{&e};
307 boost::apply_visitor(bldr, result);
311 catch(
const qi::expectation_failure<
decltype(f)>& e)
323std::optional<State::Expression> State::parseExpression(
const QString& str)
325 return parseExpression(str.toStdString());
Definition lv2_atom_helpers.hpp:99
Definition Relation.hpp:71
Definition Relation.hpp:19