#include using namespace boost::spirit; class constraint_grammar : public grammar { public: static const unsigned long PARAMETER_id = 1; static const unsigned long CONSTANT_id = 2; static const unsigned long VARIABLE_id = 3; static const unsigned long TERM_id = 4; static const unsigned long NEG_id = 5; static const unsigned long DNEG_id = 6; static const unsigned long ATOM_id = 7; static const unsigned long JUNC_id = 9; static const unsigned long PRED_id = 10; static const unsigned long EQ_id = 11; static const unsigned long LITERAL_id = 12; static const unsigned long LITERALGROUP_id = 13; static const unsigned long LITERALSET_id = 14; static const unsigned long UPDATE_id = 15; static const unsigned long ENTRY_id = 16; // s_t is scanner type template struct definition { definition(constraint_grammar const&) { // ex: ?a parameter = discard_node_d[ch_p('?')] >> lexeme_d[leaf_node_d[+lower_p]] ; // ex: mary constant = lexeme_d[leaf_node_d[+lower_p]]; // ex: X variable = lexeme_d[leaf_node_d[+upper_p]]; // one of constant, or variable term = parameter | constant | variable; // negation neg = lexeme_d[ch_p('~')]; // double-negation dneg = ch_p('~') >> ch_p('~'); // possibly negated predicate or (in)equality // (because an equality like X=Y is actually // an infix form of =(X,Y). atom = ( *(discard_node_d[dneg]) >> !neg >> (pred|eq) ) ; // con/dis-junction junc = root_node_d[ as_lower_d[str_p("and")] | as_lower_d[str_p("or")] ] >> ( literalgroup | literal ) ; // predicate name and list of terms in parens pred = root_node_d[lexeme_d[leaf_node_d[+lower_p]]] >> discard_node_d[ch_p('(')] >> term >> *(discard_node_d[ch_p(',')] >> term) >> discard_node_d[ch_p(')')] ; // (in)equality - can be seen as an infix variant of a // predicate, i.e. X=Y <-> =(X,Y) eq = term >> root_node_d[ch_p('=') | str_p("<>")] >> term; // atom, possibly connected to a con/disjunction of // other stuff literal = atom >> !junc ; // one or more literals in parenthesis, possibly with negation(s) literalgroup = *(discard_node_d[dneg]) >> !neg >> discard_node_d[ch_p('(')] >> ( literal | literalgroup ) >> discard_node_d[ch_p(')')] >> !junc ; update = root_node_d[pred]; entry = (literalgroup | literal) >> discard_node_d[ch_p(';')] >> update ; } rule,parser_tag > parameter; rule,parser_tag > constant; rule,parser_tag > variable; rule,parser_tag > term; rule,parser_tag > neg; rule,parser_tag > dneg; rule,parser_tag > atom; rule,parser_tag > junc; rule,parser_tag > pred; rule,parser_tag > eq; rule,parser_tag > literal; rule,parser_tag > literalgroup; rule,parser_tag > literalset; rule,parser_tag > update; rule,parser_tag > entry; rule, parser_tag > const& start() const { return entry; } }; };