def make_expression predicate, rel
expr = nil
lazy_expr = lazy{expr}
simple_case = sequence(keyword[:when], lazy_expr, operator[':'], lazy_expr) do |_,cond,_,val|
[cond, val]
end
full_case = sequence(keyword[:when], predicate, operator[':'], lazy_expr) do |_,cond,_,val|
[cond, val]
end
default_case = (keyword[:else] >> lazy_expr).optional
simple_when_then = sequence(lazy_expr, simple_case.many, default_case,
keyword[:end]) do |val, cases, default, _|
calculate_simple_cases(val, cases, default)
end
full_when_then = sequence(full_case.many, default_case, keyword[:end]) do |cases, default, _|
calculate_full_cases(cases, default)
end
case_expr = keyword[:case] >> (simple_when_then | full_when_then)
wildcard = operator[:*] >> WildcardExpr::Instance
lit = token(:number, :string, &ctor(LiteralExpr)) | token(:var, &ctor(VarExpr))
atom = lit | wildcard |
sequence(word, operator['.'], word|wildcard) {|owner, _, col| QualifiedColumnExpr.new owner, col} |
word(&ctor(WordExpr))
term = atom | (operator['('] >> lazy_expr << operator[')']) | case_expr
table = OperatorTable.new.
infixl(operator['+'] >> Plus, 20).
infixl(operator['-'] >> Minus, 20).
infixl(operator['*'] >> Mul, 30).
infixl(operator['/'] >> Div, 30).
infixl(operator['%'] >> Mod, 30).
prefix(operator['-'] >> Neg, 50)
expr = Expressions.build(term, table)
end