- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 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
namespace predicate {
using ...;
typedef boost::function<bool (const object &obj)> bool_func;
typedef boost::function<int (const object &obj)> int_func;
// ... скучные реализации операторов ...
template <class I, class S> struct predicate_grammar :
qi::grammar<I, bool_func(), S>
{
predicate_grammar() : predicate_grammar::base_type(bool_expr)
{
identifier = char_("a-z") >> *(char_("a-z_0-9"));
bool_prop = identifier [ _val = bind(&make_bool_prop_reader, _1, _pass) ];
bool_expr = (bool_expr2 >> "||" >> bool_expr) [ _val = bind(&make_logic_op, &op_or, _1, _2) ]
| bool_expr2 [ _val = _1 ];
bool_expr2 = (bool_expr3 >> "&&" >> bool_expr2) [ _val = bind(&make_logic_op, &op_and, _1, _2) ]
| bool_expr3 [ _val = _1 ];
bool_expr3 = ('(' >> bool_expr >> ')') [ _val = _1 ]
| ('!' >> bool_expr3) [ _val = bind(&make_not, _1) ]
| int_comp [ _val = _1 ]
| bool_prop [ _val = _1];
int_comp = (int_expr >> "<" >> int_expr) [ _val = bind(&make_cmp_op, &op_less, _1, _2) ]
| (int_expr >> "<=" >> int_expr) [ _val = bind(&make_cmp_op, &op_less_eq, _1, _2) ]
| (int_expr >> ">" >> int_expr) [ _val = bind(&make_cmp_op, &op_greater, _1, _2) ]
| (int_expr >> ">=" >> int_expr) [ _val = bind(&make_cmp_op, &op_greater_eq, _1, _2) ]
| (int_expr >> "==" >> int_expr) [ _val = bind(&make_cmp_op, &op_eq, _1, _2) ]
| (int_expr >> "!=" >> int_expr) [ _val = bind(&make_cmp_op, &op_not_eq, _1, _2) ];
int_expr = int_prop [ _val = _1 ]
| int_const [ _val = bind(&make_int_const, _1) ];
int_const = int_ [ _val = _1 ];
int_prop = identifier [ _val = bind(&make_int_prop_reader, _1, _pass) ];
}
qi::rule<I, std::string(), S> identifier;
qi::rule<I, int(), S> int_const;
qi::rule<I, int_func(), S> int_expr, int_prop;
qi::rule<I, bool_func(), S> bool_expr, bool_expr2, bool_expr3, int_comp, bool_prop;
};
boost::function<bool (const object &)> parse(const std::string &src) {
if (src.empty())
return make_bool_const(true);
bool_func p;
std::string::const_iterator b = src.begin(), e = src.end();
predicate_grammar<std::string::const_iterator, boost::spirit::ascii::space_type> grammar;
if (!phrase_parse(b, e, grammar, boost::spirit::ascii::space, p) || b != e) {
std::stringstream s;
s << "Predicate parsing failed at " << (b - src.begin()) << " in \"" << src << "\"";
throw std::runtime_error(s.str());
}
return p;
}