support OR with proper precedence
This commit is contained in:
parent
5bdc6eba93
commit
4b3417736f
|
@ -121,6 +121,28 @@ template<> struct action< and_ext >
|
||||||
static void apply( const input & in, ParserState & state )
|
static void apply( const input & in, ParserState & state )
|
||||||
{
|
{
|
||||||
std::cout << "<and>" << in.string() << std::endl;
|
std::cout << "<and>" << in.string() << std::endl;
|
||||||
|
|
||||||
|
// if we were put into an OR group we need to rearrange
|
||||||
|
auto current = state.current();
|
||||||
|
if (current->type == Predicate::Type::Or) {
|
||||||
|
auto &sub_preds = state.current()->sub_predicates;
|
||||||
|
auto second_last = sub_preds[sub_preds.size()-2];
|
||||||
|
if (second_last.type == Predicate::Type::And) {
|
||||||
|
// if we are in an OR group and second to last predicate group is
|
||||||
|
// an AND group then move the last predicate inside
|
||||||
|
second_last.sub_predicates.push_back(sub_preds.back());
|
||||||
|
sub_preds.pop_back();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// otherwise combine last two into a new AND group
|
||||||
|
Predicate pred;
|
||||||
|
pred.type = Predicate::Type::And;
|
||||||
|
pred.sub_predicates = { second_last, sub_preds.back() };
|
||||||
|
sub_preds.pop_back();
|
||||||
|
sub_preds.pop_back();
|
||||||
|
sub_preds.push_back(pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,6 +151,29 @@ template<> struct action< or_ext >
|
||||||
static void apply( const input & in, ParserState & state )
|
static void apply( const input & in, ParserState & state )
|
||||||
{
|
{
|
||||||
std::cout << "<or>" << in.string() << std::endl;
|
std::cout << "<or>" << in.string() << std::endl;
|
||||||
|
|
||||||
|
// if already an OR group do nothing
|
||||||
|
auto current = state.current();
|
||||||
|
if (current->type == Predicate::Type::Or) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if only two predicates in the group, then convert to OR
|
||||||
|
auto &sub_preds = state.current()->sub_predicates;
|
||||||
|
if (sub_preds.size()) {
|
||||||
|
current->type = Predicate::Type::Or;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// split the current group into to groups which are ORed together
|
||||||
|
Predicate pred1, pred2;
|
||||||
|
pred1.type = Predicate::Type::And;
|
||||||
|
pred2.type = Predicate::Type::And;
|
||||||
|
pred1.sub_predicates.insert(sub_preds.begin(), sub_preds.back());
|
||||||
|
pred2.sub_predicates.push_back(sub_preds.back());
|
||||||
|
|
||||||
|
current->type = Predicate::Type::Or;
|
||||||
|
sub_preds = { pred1, pred2 };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue