AST и приоритет оператора в определении правила
Привет [¹]
У меня есть простой парсер (см. Ниже).
Он намеревается анализировать условные выражения (реляционные арифметические операции и их логические комбинации).
В приведенном там примере он успешно разбирается A>5, но затем останавливается и игнорирует остальную часть ввода, и это согласуется с моим импл.
Как я могу изменитьexpr_
правило, чтобы он анализировал весь ввод?
#include
#include
#include
#include
#include
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
/// Terminals
enum metric_t : std::uint8_t { A=0u, B };
const std::string metric_names[] = { "A", "B" };
struct metrics_parser : boost::spirit::qi::symbols
{
metrics_parser()
{
this->add
( metric_names[A], A )
( metric_names[B], B )
;
}
};
/// Operators
struct op_or {};
struct op_and {};
struct op_xor {};
struct op_not {};
struct op_eq {};
struct op_lt {};
struct op_let {};
struct op_gt {};
struct op_get {};
template struct unop;
template struct binop;
/// Expression
typedef boost::variant< int,
double,
metric_t,
boost::recursive_wrapper< unop >,
boost::recursive_wrapper< binop >,
boost::recursive_wrapper< binop >,
boost::recursive_wrapper< binop >,
boost::recursive_wrapper< binop >,
boost::recursive_wrapper< binop >,
boost::recursive_wrapper< binop >
> expr;
template
struct binop
{
explicit binop(const expr& l, const expr& r) : oper1(l), oper2(r) { }
expr oper1, oper2;
};
template
struct unop
{
explicit unop(const expr& o) : oper1(o) { }
expr oper1;
};
struct printer : boost::static_visitor
{
printer(std::ostream& os) : _os(os) {}
std::ostream& _os;
void operator()(const binop& b) const { print(" and ", b.oper1, b.oper2); }
void operator()(const binop& b) const { print(" or ", b.oper1, b.oper2); }
void operator()(const binop& b) const { print(" xor ", b.oper1, b.oper2); }
void operator()(const binop& b) const { print(" = ", b.oper1, b.oper2); }
void operator()(const binop& b) const { print(" < ", b.oper1, b.oper2); }
void operator()(const binop& b) const { print(" > ", b.oper1, b.oper2); }
void print(const std::string& op, const expr& l, const expr& r) const
{
_os < "(";
boost::apply_visitor(*this, l);
_os < op;
boost::apply_visitor(*this, r);
_os < ")";
}
void operator()(const unop> number_r_)
[ _val = phx::construct< binop >(
phx::construct< binop >(_1,_2),
phx::construct< binop >(_1,_2) )
] |
(metric_r_ >> "