def read_single_expression
token = next_token
if !token
parse_error(nil, "Expected expression!")
elsif unary_operator?(token)
operand = read_single_expression
Query::UnaryOperator.new(token, operand)
elsif token == '"'
phrase_terms = []
until (term = next_token) == '"'
phrase_terms << Query::Term.new(term)
end
Query::Phrase.new(phrase_terms)
elsif token == '{' || token == '['
left = next_token
parse_error(left, "Expected left term in range query") if !left
to = next_token
parse_error(left, "Expected TO in range query") if to != "TO"
right = next_token
parse_error(right, "Expected left term in range query") if !right
end_range = next_token
parse_error(right, "Expected end range '#{end_range}") if !['}', ']'].include?(end_range)
Query::RangeQuery.new(left, right, token == '[', end_range == ']')
elsif token == '('
subquery = read_expression
close_paren = next_token
parse_error(close_paren, "Expected ')'") if close_paren != ')'
Query::Subquery.new(subquery)
elsif ['}',']',')'].include?(token)
parse_error(token, "Unexpected end paren")
elsif binary_operator?(token)
parse_error(token, "Unexpected binary operator")
else
term = Query::Term.new(token)
if peek_token == ':'
Query::BinaryOperator.new(term, next_token, read_single_expression)
else
term
end
end
end