#
include
<boost/spirit/
include
/qi.hpp>
#
include
<boost/variant/recursive_wrapper.hpp>
using
namespace
boost::spirit;
using
namespace
boost::spirit::qi;
struct op_or {};
struct op_and {};
struct op_xor {};
typedef std::string
var
;
template <typename tag> struct binop;
template <typename tag> struct unop;
typedef boost::variant<
var
,
boost::recursive_wrapper<unop <op_not> >,
boost::recursive_wrapper<binop<op_and> >,
boost::recursive_wrapper<binop<op_xor> >,
boost::recursive_wrapper<binop<op_or> >
> expr;
template <typename tag> struct binop
{
explicit binop(
const
expr& l,
const
expr& r) : oper1(l), oper2(r) { }
expr oper1, oper2;
};
template <typename tag> struct unop
{
explicit unop(
const
expr& o) : oper1(o) { }
expr oper1;
};
template <typename It, typename Skipper = qi::space_type>
struct parser : qi::grammar<It, expr(), Skipper>
{
parser() : parser::base_type(expr_)
{
using
namespace
qi;
expr_ = or_.alias();
not_ = (
"not"
> simple ) [ _val = phx::construct<unop <op_not> >(_1) ] | simple [ _val = _1 ];
or_ = (xor_ >>
"or"
>> or_ ) [ _val = phx::construct<binop<op_or> >(_1, _2) ] | xor_ [ _val = _1 ];
xor_ = (and_ >>
"xor"
>> xor_) [ _val = phx::construct<binop<op_xor> >(_1, _2) ] | and_ [ _val = _1 ];
and_ = (not_ >>
"and"
>> and_) [ _val = phx::construct<binop<op_and> >(_1, _2) ] | not_ [ _val = _1 ];
simple = ((
'('
> expr_ >
')'
) | var_);
var_ = qi::lexeme[ +alpha ];
}
private
:
qi::rule<It,
var
() , Skipper> var_;
qi::rule<It, expr(), Skipper> not_, and_, xor_, or_, simple, expr_;
};