Last active
March 27, 2017 11:49
-
-
Save markpapadakis/d2c7897736f58fea26ccbac7e915571e to your computer and use it in GitHub Desktop.
Yak Shaving: spending a whole weekend going through variations/alternative implementations until a utility function impl. feels 'right'.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct query_assign_ctx | |
{ | |
uint32_t nextIndex; | |
std::vector<std::vector<phrase *> *> stack; | |
}; | |
static void assign_query_indices(ast_node *const n, query_assign_ctx &ctx) | |
{ | |
if (n->is_unary()) | |
{ | |
if (ctx.stack.size()) | |
ctx.stack.back()->push_back(n->p); | |
n->p->index = ctx.nextIndex; | |
ctx.nextIndex += n->p->size; | |
} | |
else if (n->type == ast_node::Type::UnaryOp) | |
assign_query_indices(n->unaryop.expr, ctx); | |
else if (n->type == ast_node::Type::ConstTrueExpr) | |
assign_query_indices(n->expr, ctx); | |
else if (n->type == ast_node::Type::BinOp) | |
{ | |
const auto lhs = n->binop.lhs, rhs = n->binop.rhs; | |
const auto op = n->binop.op; | |
if (op == Operator::AND || op == Operator::STRICT_AND) | |
{ | |
auto u = std::make_unique<std::vector<phrase *>>(); | |
ctx.stack.push_back(u.get()); | |
assign_query_indices(lhs, ctx); | |
ctx.stack.pop_back(); | |
for (auto p : *u) | |
p->toNextSpan = ctx.nextIndex - p->index; | |
assign_query_indices(rhs, ctx); | |
} | |
else if (op == Operator::NOT) | |
{ | |
// We do not care for the RHS(not) | |
// but we need to advance nextIndex by 4 so that we won't consider whatever's on the RHS adjacent to whatever was before the LHS | |
ctx.nextIndex += 4; | |
assign_query_indices(rhs, ctx); | |
} | |
else | |
{ | |
// This is a bit more involved because of the semantics we are trying to enforce | |
// re: OR groups and phrases | |
const auto saved{ctx.nextIndex}; | |
assign_query_indices(lhs, ctx); | |
const auto maxL{ctx.nextIndex}; | |
ctx.nextIndex = saved; | |
assign_query_indices(rhs, ctx); | |
const auto maxR{ctx.nextIndex}; | |
ctx.nextIndex = std::max(maxL, maxR); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment