2 #include "ErrorHandler/MessageAnalyzer/ma_parse.h"
4 #include "ErrorHandler/MessageAnalyzer/ma_types.h"
6 #include "ErrorHandler/MessageAnalyzer/ma_boolean_andexpr.h"
7 #include "ErrorHandler/MessageAnalyzer/ma_boolean_cond.h"
8 #include "ErrorHandler/MessageAnalyzer/ma_boolean_expr.h"
10 #include "ErrorHandler/MessageAnalyzer/ma_domain_andexpr.h"
11 #include "ErrorHandler/MessageAnalyzer/ma_domain_cond.h"
12 #include "ErrorHandler/MessageAnalyzer/ma_domain_expr.h"
14 #include "ErrorHandler/MessageAnalyzer/ma_cond_test_andexpr.h"
15 #include "ErrorHandler/MessageAnalyzer/ma_cond_test_expr.h"
16 #include "ErrorHandler/MessageAnalyzer/ma_cond_test_primary.h"
18 #include "ErrorHandler/MessageAnalyzer/ma_rule.h"
20 #include <boost/any.hpp>
21 #include <boost/spirit/include/phoenix_bind.hpp>
22 #include <boost/spirit/include/phoenix_core.hpp>
23 #include <boost/spirit/include/phoenix_operator.hpp>
24 #include <boost/spirit/include/qi.hpp>
26 namespace ascii = ::boost::spirit::ascii;
27 namespace phx = ::boost::phoenix;
28 namespace qi = ::boost::spirit::qi;
29 namespace ql = ::boost::spirit::qi::labels;
53 using novadaq::errorhandler::CO_E;
54 using novadaq::errorhandler::CO_G;
55 using novadaq::errorhandler::CO_GE;
56 using novadaq::errorhandler::CO_L;
57 using novadaq::errorhandler::CO_LE;
58 using novadaq::errorhandler::CO_NE;
59 using novadaq::errorhandler::compare_op_t;
60 using novadaq::errorhandler::cond_arg_t;
61 using novadaq::errorhandler::cond_idx_t;
73 using novadaq::errorhandler::NONE;
74 using novadaq::errorhandler::SOURCE;
75 using novadaq::errorhandler::TARGET;
80 namespace errorhandler {
81 template<
class FwdIter,
class Skip>
84 template<
class FwdIter,
class Skip>
87 template<
class FwdIter,
class Skip>
99 expr.insert_andexpr(andexpr);
105 andexpr.insert_cond(cond);
111 cond.insert_expr(expr);
118 rule->update_notify_list(name, (arg ==
's') ? SOURCE : TARGET);
121 cond.insert_cond_arg(rule->get_cond_idx(name), (arg ==
's') ? SOURCE : TARGET, rule->get_cond_size());
127 cond.insert_str_cond(str);
132 template<
class FwdIter,
class Skip>
134 : qi::grammar<FwdIter, ma_domain_expr(), Skip>
137 domain_expr_parser(
ma_rule* rule);
140 qi::rule<FwdIter, ma_domain_expr(), Skip> domain_expr;
141 qi::rule<FwdIter, ma_domain_andexpr(), Skip> domain_andexpr;
142 qi::rule<FwdIter, ma_domain_cond(), locals<std::string>, Skip> domain_cond;
144 qi::rule<FwdIter, std::string(), Skip> key;
145 qi::rule<FwdIter, std::string(), Skip> keywords;
146 qi::rule<FwdIter, std::string(), Skip> str;
151 template<
class FwdIter,
class Skip>
153 : domain_expr_parser::base_type(domain_expr)
156 domain_andexpr[phx::bind(&insert_domain_andexpr, ql::_val, ql::_1)] %
"OR";
159 domain_cond[phx::bind(&insert_domain_cond, ql::_val, ql::_1)] %
"AND";
162 (lit(
'(') >> domain_expr[phx::bind(&insert_domain_expr, ql::_val, ql::_1)] >> lit(
')'))
166 key[ql::_a = ql::_1] >>
".$" >> char_(
"st")
167 [phx::bind(&insert_cond_arg, ql::_val, ql::_a, ql::_1, rule)]) %
169 -(
'=' >> (str[phx::bind(&insert_str_cond, ql::_val, ql::_1)] |
"ANY")))
173 keywords = no_case[
"AND"] | no_case[
"OR"] | no_case[
"ANY"];
175 key = qi::lexeme[char_(
"a-zA-Z_") >> *char_(
"a-zA-Z_0-9")] - keywords;
178 str = qi::lexeme[
'\'' >> +(ascii::char_ -
'\'') >>
'\''];
186 expr.insert(andexpr);
192 andexpr.insert(cond);
198 cond.insert_expr(expr);
209 cond.insert_cond(rule->insert_condition_ptr(name,
true));
213 insert_ext_func(
ma_boolean_cond& cond, std::string
const&
function, std::string
const& name,
char cond_arg, std::vector<boost::any>
const& func_args,
ma_rule* rule)
215 cond.insert_ext_func(rule->insert_condition_ptr(name,
false ), (cond_arg ==
's') ? SOURCE : ((cond_arg ==
't') ? TARGET : NONE), func_args,
function);
219 insert_compare_op_double(
ma_boolean_cond& cond, compare_op_t op,
double rhv)
221 cond.insert_compare_op_double(op, rhv);
225 insert_compare_op_bool(
ma_boolean_cond& cond, compare_op_t op,
bool rhv)
227 if ((op != CO_E) && (op != CO_NE))
228 throw std::runtime_error(
"error in parsing rule: booleans can only use == or !=");
230 cond.insert_compare_op_bool(op, rhv);
234 insert_compare_op_string(
ma_boolean_cond& cond, compare_op_t op, std::string rhv)
236 cond.insert_compare_op_string(op, rhv);
242 typedef std::vector<any> anys;
244 template<
class FwdIter,
class Skip>
246 : qi::grammar<FwdIter, ma_boolean_expr(), Skip>
249 boolean_expr_parser(
ma_rule* rule);
252 qi::rule<FwdIter, ma_boolean_expr(), Skip> boolean_expr;
253 qi::rule<FwdIter, ma_boolean_andexpr(), Skip> boolean_andexpr;
254 qi::rule<FwdIter, ma_boolean_cond(), locals<std::string, char, compare_op_t, std::string, anys>, Skip> boolean_cond;
256 qi::rule<FwdIter, std::string(), Skip> key;
257 qi::rule<FwdIter, std::string(), Skip> str;
258 qi::rule<FwdIter, std::string(), Skip> keywords;
259 qi::rule<FwdIter, compare_op_t(), Skip> compare_op;
261 qi::rule<FwdIter, any(), Skip> arg;
262 qi::rule<FwdIter, anys(), Skip> args;
267 template<
class FwdIter,
class Skip>
269 : boolean_expr_parser::base_type(boolean_expr)
272 boolean_andexpr[phx::bind(&insert_boolean_andexpr, ql::_val, ql::_1)] %
"||";
275 boolean_cond[phx::bind(&insert_boolean_cond, ql::_val, ql::_1)] %
"&&";
278 (lit(
'(') >> boolean_expr[phx::bind(&insert_boolean_expr, ql::_val, ql::_1)] >>
')')
280 (key[ql::_a = ql::_1] >> lit(
'(') >> key[ql::_d = ql::_1] >> -(
".$" >> char_(
"st")[ql::_b = ql::_1]) >> -(
',' >> args[ql::_e = ql::_1]) >> lit(
')')[phx::bind(&insert_ext_func, ql::_val, ql::_a, ql::_d, ql::_b, ql::_e, rule)]
282 >> -(compare_op[ql::_c = ql::_1] >> (double_[phx::bind(&insert_compare_op_double, ql::_val, ql::_c, ql::_1)] | bool_[phx::bind(&insert_compare_op_bool, ql::_val, ql::_c, ql::_1)] | str[phx::bind(&insert_compare_op_string, ql::_val, ql::_c, ql::_1)])))
284 key[phx::bind(&insert_primitive_cond, ql::_val, ql::_1, rule)]
290 arg = double_[ql::_val = ql::_1] | bool_[ql::_val = ql::_1] | str[ql::_val = ql::_1];
292 keywords = no_case[
"AND"] | no_case[
"OR"];
294 key = qi::lexeme[char_(
"a-zA-Z_") >> *char_(
"a-zA-Z_0-9")] - keywords;
296 str = qi::lexeme[
'\'' >> +(char_ -
'\'') >>
'\''];
298 compare_op = lit(
"==")[ql::_val = CO_E] | lit(
"!=")[ql::_val = CO_NE] | lit(
"<=")[ql::_val = CO_LE] | lit(
">=")[ql::_val = CO_GE] | lit(
"<")[ql::_val = CO_L] | lit(
">")[ql::_val = CO_G];
306 rule->set_boolean_expr(expr);
312 rule->set_domain_expr(expr);
317 bool novadaq::errorhandler::parse_condition_expr(std::string
const& s,
ma_rule* rule)
319 typedef std::string::const_iterator iter_t;
320 typedef ascii::space_type ws_t;
322 boolean_expr_parser<iter_t, ws_t> boolean_p(rule);
323 domain_expr_parser<iter_t, ws_t> domain_p(rule);
325 iter_t begin = s.begin();
326 iter_t
const end = s.end();
328 bool b = qi::phrase_parse(
329 begin, end, boolean_p[phx::bind(&set_boolean_expr, ql::_1, rule)] >> -(
"WHERE" >> domain_p[phx::bind(&set_domain_expr, ql::_1, rule)]), space) &&
342 andexpr.insert(primary);
348 expr.insert(andexpr);
354 primary.insert_expr(expr);
358 insert_test_func(
ma_cond_test_primary& primary, std::string
const&
function, std::vector<boost::any>
const& func_args)
360 primary.insert_func(
function, func_args);
366 primary.insert_compare_op(op, rhv);
374 static bool const expect_dot =
true;
377 template<
class FwdIter,
class Skip>
379 : qi::grammar<FwdIter, ma_cond_test_expr(), Skip>
382 cond_test_expr_parser();
385 qi::rule<FwdIter, ma_cond_test_expr(), Skip> test_expr;
386 qi::rule<FwdIter, ma_cond_test_andexpr(), Skip> test_andexpr;
387 qi::rule<FwdIter, ma_cond_test_primary(), locals<std::string, anys_t, compare_op_t>, Skip> test_primary;
389 qi::rule<FwdIter, std::string(), Skip> key;
390 qi::rule<FwdIter, std::string(), Skip> str;
391 qi::rule<FwdIter, std::string(), Skip> keywords;
392 qi::rule<FwdIter, compare_op_t(), Skip> compare_op;
394 qi::rule<FwdIter, any(), Skip> value;
395 qi::rule<FwdIter, anys(), Skip> values;
397 qi::real_parser<double, strict_real_policies<double> > real;
402 template<
class FwdIter,
class Skip>
404 : cond_test_expr_parser::base_type(test_expr)
407 test_andexpr[phx::bind(&insert_test_andexpr, ql::_val, ql::_1)] %
"||";
410 test_primary[phx::bind(&insert_test_primary, ql::_val, ql::_1)] %
"&&";
413 (lit(
'(') >> test_expr[phx::bind(&insert_test_expr, ql::_val, ql::_1)] >> lit(
')')) |
414 (key[ql::_a = ql::_1] >> lit(
'(') >> -values[ql::_b = ql::_1] >> lit(
')')[phx::bind(&insert_test_func, ql::_val, ql::_a, ql::_b)] >> -(compare_op[ql::_c = ql::_1] >> value[phx::bind(&insert_test_compare_op, ql::_val, ql::_c, ql::_1)]));
416 values = (value %
',');
418 value = (int_[ql::_val = ql::_1] >> !char_(
".eE")) | double_[ql::_val = ql::_1] | bool_[ql::_val = ql::_1] | str[ql::_val = ql::_1];
420 keywords = no_case[
"AND"] | no_case[
"OR"];
422 key = qi::lexeme[char_(
"a-zA-Z_") >> *char_(
"a-zA-Z_0-9")] - keywords;
424 str = qi::lexeme[
'\'' >> +(char_ -
'\'') >>
'\''];
426 compare_op = lit(
"==")[ql::_val = CO_E] | lit(
"!=")[ql::_val = CO_NE] | lit(
"<=")[ql::_val = CO_LE] | lit(
">=")[ql::_val = CO_GE] | lit(
"<")[ql::_val = CO_L] | lit(
">")[ql::_val = CO_G];
431 bool novadaq::errorhandler::parse_condition_test(std::string
const& s,
ma_cond_test_expr& expr)
433 typedef std::string::const_iterator iter_t;
434 typedef ascii::space_type ws_t;
436 if (s.empty())
return true;
438 cond_test_expr_parser<iter_t, ws_t> test_p;
440 iter_t begin = s.begin();
441 iter_t
const end = s.end();
443 bool b = qi::phrase_parse(begin, end, test_p, space, expr) && begin == end;
boolean and-expression consists of a list of boolean elemental conditions connected with 'AND' operat...