2 #include "ErrorHandler/MessageAnalyzer/ma_parse.h"
4 #include "ErrorHandler/MessageAnalyzer/ma_types.h"
6 #include "ErrorHandler/MessageAnalyzer/ma_boolean_expr.h"
7 #include "ErrorHandler/MessageAnalyzer/ma_boolean_andexpr.h"
8 #include "ErrorHandler/MessageAnalyzer/ma_boolean_cond.h"
10 #include "ErrorHandler/MessageAnalyzer/ma_domain_expr.h"
11 #include "ErrorHandler/MessageAnalyzer/ma_domain_andexpr.h"
12 #include "ErrorHandler/MessageAnalyzer/ma_domain_cond.h"
14 #include "ErrorHandler/MessageAnalyzer/ma_cond_test_expr.h"
15 #include "ErrorHandler/MessageAnalyzer/ma_cond_test_andexpr.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/qi.hpp>
22 #include <boost/spirit/include/phoenix_bind.hpp>
23 #include <boost/spirit/include/phoenix_core.hpp>
24 #include <boost/spirit/include/phoenix_operator.hpp>
27 namespace ascii = ::boost::spirit::ascii;
28 namespace phx = ::boost::phoenix;
29 namespace qi = ::boost::spirit::qi;
30 namespace ql = ::boost::spirit::qi::labels;
65 using novadaq::errorhandler::cond_idx_t;
66 using novadaq::errorhandler::cond_arg_t;
67 using novadaq::errorhandler::compare_op_t;
68 using novadaq::errorhandler::SOURCE;
69 using novadaq::errorhandler::TARGET;
70 using novadaq::errorhandler::NONE;
71 using novadaq::errorhandler::CO_LE;
72 using novadaq::errorhandler::CO_GE;
73 using novadaq::errorhandler::CO_NE;
74 using novadaq::errorhandler::CO_E;
75 using novadaq::errorhandler::CO_L;
76 using novadaq::errorhandler::CO_G;
84 namespace errorhandler
86 template<
class FwdIter,
class Skip>
89 template<
class FwdIter,
class Skip>
92 template<
class FwdIter,
class Skip>
106 expr.insert_andexpr(andexpr);
113 andexpr.insert_cond(cond);
120 cond.insert_expr(expr);
125 , std::string
const & name
130 rule->update_notify_list( name
131 , (arg==
's') ? SOURCE : TARGET );
134 cond.insert_cond_arg ( rule->get_cond_idx(name)
135 , (arg==
's') ? SOURCE : TARGET
136 , rule->get_cond_size() );
142 cond.insert_str_cond( str );
148 template<
class FwdIter,
class Skip >
150 : qi::grammar<FwdIter, ma_domain_expr(), Skip>
154 domain_expr_parser(
ma_rule * rule );
157 qi::rule<FwdIter, ma_domain_expr(), Skip> domain_expr;
158 qi::rule<FwdIter, ma_domain_andexpr(), Skip> domain_andexpr;
159 qi::rule<FwdIter, ma_domain_cond(), locals<std::string>, Skip> domain_cond;
161 qi::rule<FwdIter, std::string(), Skip> key;
162 qi::rule<FwdIter, std::string(), Skip> keywords;
163 qi::rule<FwdIter, std::string(), Skip> str;
170 template<
class FwdIter,
class Skip >
173 : domain_expr_parser::base_type( domain_expr )
176 domain_andexpr [phx::bind(&insert_domain_andexpr, ql::_val, ql::_1)]
181 domain_cond [phx::bind(&insert_domain_cond, ql::_val, ql::_1)]
188 >> domain_expr [phx::bind(&insert_domain_expr, ql::_val, ql::_1)]
195 key [ql::_a = ql::_1]
198 [phx::bind(&insert_cond_arg, ql::_val, ql::_a, ql::_1, rule)]
200 ) >> -(
'=' >> ( str [phx::bind(&insert_str_cond, ql::_val, ql::_1)]
208 keywords = no_case[
"AND"]
213 key = qi::lexeme[char_(
"a-zA-Z_") >> *char_(
"a-zA-Z_0-9")]
217 str = qi::lexeme[
'\'' >> +(ascii::char_ -
'\'') >>
'\''];
227 expr.insert(andexpr);
234 andexpr.insert(cond);
241 cond.insert_expr(expr);
246 , std::string
const & name
254 cond.insert_cond( rule->insert_condition_ptr( name,
true ) );
259 , std::string
const &
function
260 , std::string
const & name
262 , std::vector<boost::any>
const & func_args
265 cond.insert_ext_func( rule->insert_condition_ptr( name,
false )
266 , (cond_arg==
's') ? SOURCE : ((cond_arg==
't') ? TARGET : NONE)
276 cond.insert_compare_op_double( op, rhv );
284 if( (op != CO_E) && (op != CO_NE) )
285 throw std::runtime_error(
"error in parsing rule: booleans can only use == or !=");
287 cond.insert_compare_op_bool( op, rhv );
295 cond.insert_compare_op_string( op, rhv );
301 typedef std::vector<any> anys;
303 template<
class FwdIter,
class Skip >
305 : qi::grammar<FwdIter, ma_boolean_expr(), Skip>
309 boolean_expr_parser(
ma_rule * rule );
312 qi::rule<FwdIter, ma_boolean_expr(), Skip> boolean_expr;
313 qi::rule<FwdIter, ma_boolean_andexpr(), Skip> boolean_andexpr;
315 , locals<std::string, char, compare_op_t, std::string, anys>
316 , Skip> boolean_cond;
318 qi::rule<FwdIter, std::string(), Skip> key;
319 qi::rule<FwdIter, std::string(), Skip> str;
320 qi::rule<FwdIter, std::string(), Skip> keywords;
321 qi::rule<FwdIter, compare_op_t(), Skip> compare_op;
323 qi::rule<FwdIter, any(), Skip> arg;
324 qi::rule<FwdIter, anys(), Skip> args;
331 template<
class FwdIter,
class Skip >
334 : boolean_expr_parser::base_type( boolean_expr )
337 boolean_andexpr [phx::bind(&insert_boolean_andexpr, ql::_val, ql::_1)]
342 boolean_cond [phx::bind(&insert_boolean_cond, ql::_val, ql::_1)]
348 >> boolean_expr [phx::bind(&insert_boolean_expr,ql::_val,ql::_1)]
353 key [ ql::_a = ql::_1 ]
354 >> lit(
'(') >> key [ ql::_d = ql::_1 ]
355 >> -(
".$" >> char_(
"st") [ ql::_b = ql::_1 ] )
356 >> -(
',' >> args [ ql::_e = ql::_1 ] )
357 >> lit(
')') [ phx::bind( &insert_ext_func
358 , ql::_val, ql::_a, ql::_d, ql::_b, ql::_e, rule ) ]
360 >> -( compare_op [ ql::_c = ql::_1 ]
362 double_ [ phx::bind( &insert_compare_op_double
363 , ql::_val, ql::_c, ql::_1 ) ]
364 | bool_ [ phx::bind( &insert_compare_op_bool
365 , ql::_val, ql::_c, ql::_1 ) ]
366 | str [ phx::bind( &insert_compare_op_string
367 , ql::_val, ql::_c, ql::_1 ) ]
372 key [ phx::bind( &insert_primitive_cond, ql::_val, ql::_1, rule) ]
379 arg = double_ [ ql::_val = ql::_1 ]
380 | bool_ [ ql::_val = ql::_1 ]
381 | str [ ql::_val = ql::_1 ]
384 keywords = no_case[
"AND"]
388 key = qi::lexeme[char_(
"a-zA-Z_") >> *char_(
"a-zA-Z_0-9")]
392 str = qi::lexeme[
'\'' >> +(char_ -
'\'') >>
'\'']
395 compare_op = lit(
"==") [ ql::_val = CO_E ]
396 | lit(
"!=") [ ql::_val = CO_NE ]
397 | lit(
"<=") [ ql::_val = CO_LE ]
398 | lit(
">=") [ ql::_val = CO_GE ]
399 | lit(
"<" ) [ ql::_val = CO_L ]
400 | lit(
">" ) [ ql::_val = CO_G ]
410 rule->set_boolean_expr( expr );
416 rule->set_domain_expr( expr );
423 novadaq::errorhandler::parse_condition_expr ( std::string
const & s
426 typedef std::string::const_iterator iter_t;
427 typedef ascii::space_type ws_t;
429 boolean_expr_parser<iter_t, ws_t> boolean_p(rule);
430 domain_expr_parser<iter_t, ws_t> domain_p(rule);
432 iter_t begin = s.begin();
433 iter_t
const end = s.end();
435 bool b = qi::phrase_parse
438 , boolean_p [phx::bind(&set_boolean_expr, ql::_1, rule)]
439 >> -(
"WHERE" >> domain_p
440 [phx::bind(&set_domain_expr , ql::_1, rule)]
458 andexpr.insert( primary );
465 expr.insert( andexpr );
472 primary.insert_expr( expr );
477 , std::string
const &
function
478 , std::vector<boost::any>
const & func_args )
480 primary.insert_func(
function, func_args );
486 , boost::any
const & rhv )
488 primary.insert_compare_op( op, rhv );
494 template <
typename T>
497 static bool const expect_dot =
true;
501 template<
class FwdIter,
class Skip >
503 : qi::grammar<FwdIter, ma_cond_test_expr(), Skip>
507 cond_test_expr_parser( );
510 qi::rule<FwdIter, ma_cond_test_expr(), Skip> test_expr;
511 qi::rule<FwdIter, ma_cond_test_andexpr(), Skip> test_andexpr;
513 , locals<std::string, anys_t, compare_op_t>
514 , Skip> test_primary;
516 qi::rule<FwdIter, std::string(), Skip> key;
517 qi::rule<FwdIter, std::string(), Skip> str;
518 qi::rule<FwdIter, std::string(), Skip> keywords;
519 qi::rule<FwdIter, compare_op_t(), Skip> compare_op;
521 qi::rule<FwdIter, any(), Skip> value;
522 qi::rule<FwdIter, anys(), Skip> values;
524 qi::real_parser< double, strict_real_policies<double> > real;
530 template<
class FwdIter,
class Skip >
533 : cond_test_expr_parser::base_type( test_expr )
536 test_andexpr [phx::bind(&insert_test_andexpr, ql::_val, ql::_1)]
541 test_primary [phx::bind(&insert_test_primary, ql::_val, ql::_1)]
548 >> test_expr [phx::bind(&insert_test_expr, ql::_val, ql::_1)]
553 key [ ql::_a = ql::_1 ]
555 >> - values [ ql::_b = ql::_1 ]
556 >> lit(
')') [ phx::bind(&insert_test_func, ql::_val, ql::_a, ql::_b) ]
557 >> -( compare_op [ ql::_c = ql::_1 ]
558 >> value [ phx::bind( &insert_test_compare_op
559 , ql::_val, ql::_c, ql::_1 ) ]
564 values = ( value %
',' )
567 value = ( int_ [ ql::_val = ql::_1 ] >> ! char_(
".eE") )
568 | double_ [ ql::_val = ql::_1 ]
569 | bool_ [ ql::_val = ql::_1 ]
570 | str [ ql::_val = ql::_1 ]
573 keywords = no_case[
"AND"] | no_case[
"OR"]
576 key = qi::lexeme[char_(
"a-zA-Z_") >> *char_(
"a-zA-Z_0-9")]
580 str = qi::lexeme[
'\'' >> +(char_ -
'\'') >>
'\'']
583 compare_op = lit(
"==") [ ql::_val = CO_E ]
584 | lit(
"!=") [ ql::_val = CO_NE ]
585 | lit(
"<=") [ ql::_val = CO_LE ]
586 | lit(
">=") [ ql::_val = CO_GE ]
587 | lit(
"<" ) [ ql::_val = CO_L ]
588 | lit(
">" ) [ ql::_val = CO_G ]
598 novadaq::errorhandler::parse_condition_test ( std::string
const & s
601 typedef std::string::const_iterator iter_t;
602 typedef ascii::space_type ws_t;
604 if( s.empty() )
return true;
606 cond_test_expr_parser<iter_t, ws_t> test_p;
608 iter_t begin = s.begin();
609 iter_t
const end = s.end();
611 bool b = qi::phrase_parse ( begin, end , test_p , space , expr )