Создаю граматику для вычисления выражения. Использую Boost.spirit.qi. Написал граматику следующего вида:
using namespace qi;
using It = std::string::iterator;
qi::rule<It, double(), qi::space_type> arith_expression, arith_term, arith_factor;
qi::rule<It, double(), qi::space_type> b_expression, b_term, b_factor;
auto literal = double_;
arith_factor = literal
| '(' >> arith_expression >> ')'
| '-' >> arith_factor
| '+' >> arith_factor
| '(' >> b_expression >> ')'
;
arith_term = arith_factor [_val = _1] >> *('*' >> arith_factor [_val *= _1]
| '/' >> arith_factor [_val /= _1]
);
arith_expression = arith_term [_val = _1] >> *('+' >> arith_term [_val += _1]
| '-' >> arith_term [_val -= _1]
)
;
qi::rule<It, double()> relation;
relation = arith_expression [_val = _1] >> *(qi::lit("==") >> arith_expression [_val = (_val == _1)] );
auto b_literal = double_;
b_factor = b_literal [_val = _1]
| '(' >> b_expression [_val = _1] >> ')'
| qi::lit("not") >> b_factor [_val = !_1]
| relation [_val = _1]
;
b_term = b_factor [_val = _1] >> *(qi::lit("and") >> b_factor [_val = (_val && _1)]);
b_expression = b_term [_val = _1] >> *(qi::lit("or") >> b_term [_val = (_val || _1)] );
Но почему то она не компилируется, хотя по отдельности и бинарное и арифметическое выражения работают отлично. Как только добавляю отношение(relation) то все начинает "падать" во время компиляции. Может быть я неправльно составил граматику при добавлении оператора отношения либо я не доконца понял boost.spirit.qi. Вот фрагмент ошибки компиляции:
error: no match for call to ‘(const function_type {aka const boost::function<bool(__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, boost::spirit::context<boost::fusion::cons<double&, boost::fusion::nil_>, boost::fusion::vector<> >&, const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >&)>}) (__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >, double(), boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >, 0> >::context_type&, const boost::spirit::unused_type&)’
if (f(first, last, context, skipper))
^~
In file included from /usr/include/boost/function/detail/maybe_include.hpp:43:0,
from /usr/include/boost/function/detail/function_iterate.hpp:14,
from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:67,
from /usr/include/boost/function.hpp:70,
from /usr/include/boost/spirit/home/qi/nonterminal/rule.hpp:16,
from /usr/include/boost/spirit/home/qi/nonterminal.hpp:14,
from /usr/include/boost/spirit/home/qi.hpp:21,
from /usr/include/boost/spirit/include/qi.hpp:16,
from grammar.cpp:6:
/usr/include/boost/function/function_template.hpp:754:17: note: candidate: boost::function4<R, T1, T2, T3, T4>::result_type boost::function4<R, T1, T2, T3, T4>::operator()(T0, T1, T2, T3) const [with R = bool; T0 = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<double&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >&; boost::function4<R, T1, T2, T3, T4>::result_type = bool]
result_type operator()(BOOST_FUNCTION_PARMS) const
^~~~~~~~
/usr/include/boost/function/function_template.hpp:754:17: note: no known conversion for argument 4 from ‘const boost::spirit::unused_type’ to ‘const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::standard> >&’
Разобрался.Нужно так: `
qi::rule expression, additive, multiplicative, relationship, factor;
expression = relationship [_val = _1];
relationship = additive [_val = _1]
>> *(
lit("==") >> additive [_val = (_val == _1)]
| lit("!=") >> additive [_val = (_val != _1)]
| lit("<" ) >> additive [_val = (_val < _1)]
| lit(">" ) >> additive [_val = (_val > _1)]
| lit("<=") >> additive [_val = (_val <= _1)]
| lit(">=") >> additive [_val = (_val >= _1)]
)
;
additive = multiplicative [_val = _1]
>> *(
lit("+") >> multiplicative [_val += _1]
| lit("-") >> multiplicative [_val += _1]
| lit("or") >> multiplicative [_val == (_val || _1)]
)
;
multiplicative = factor [_val = _1]
>> *(
lit("*") >> factor [_val *= _1]
| lit("/") >> factor [_val /= _1]
| lit("and") >> factor [_val = (_val && _1)]
)
;
factor = double_ [_val = _1]
| bool_ [_val = _1]
| lit("(") >> expression [_val = _1] >> lit(")")
| lit("-") >> factor [_val = -_1]
| lit("+") >> factor [_val = +_1]
| lit("not") >> factor [_val = !(_1)]
;`
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть 2 таблицы products(id,product_name,price) и reviews(id,product_id,commentary)
Есть List, каждый image из которого я кладу на рандомные координаты в canvasПроблема в том что, первое и второе изображение отображаются нормально,...