Real filters combine conditions, and AND binds tighter than OR. Today you parse boolean expressions so that the tree reflects the correct precedence without any parentheses.
Parse AND and OR combinations of comparisons into a tree where AND binds tighter than OR.
WHERE a = 1 AND b = 2 OR c = 3 has to mean (a = 1 AND b = 2) OR c = 3 - AND
binds more tightly than OR, just like * binds tighter than + in
arithmetic. The classic recursive-descent way to encode this is one function
per precedence level: an OR parser that calls an AND parser for each of its
operands, and an AND parser that calls the comparison parser for each of its.
Because the outer level is the lowest-precedence operator, OR ends up at the
top of the tree and the tighter AND groups sit beneath it - exactly the
structure you want when the executor walks it. This layering is the core trick of
recursive-descent parsing; the same shape scales to as many precedence levels as
a language needs.
// layered rules encode precedence:// parseOr -> parseAnd ( OR parseAnd )*// parseAnd -> parseCompare ( AND parseCompare )*// the lowest-precedence operator sits at the top of the tree