    /*
     *  call-seq:
     *     query_parser.parse(query_string) -> Query
     *
     *  Parse a query string returning a Query object if parsing was successful.
     *  Will raise a QueryParseException if unsuccessful.
     */
    static VALUE
    frb_qp_parse(VALUE self, VALUE rstr)
    {
        const char *msg = NULL;
        volatile VALUE rq;
        GET_QP;
        rstr = rb_obj_as_string(rstr);
        TRY
            rq = frb_get_q(qp_parse(qp, rs2s(rstr)));
            break;
        default:
            msg = xcontext.msg;
            HANDLED();
        XENDTRY

        if (msg) {
            rb_raise(cQueryParseException, "%s", msg);
        }

        return rq;
    }