let of_string str : t =
    let fail msg =
      raise (Parse_error (sprintf "Request Syntax Error: %s" msg)) in
    let atom_list l =
      Ls.map l ~f:(function Sx.Atom s -> s
                   | _ -> fail "Expecting list of atoms"in
    let rec parse_expr =
      function
      | Sx.Atom s -> fail (sprintf "Unexpected atom: %s" s)
      | Sx.List ((Sx.Atom "and") :: args) ->
          if args =@= [] then
            fail "'and' expects arguments"
          else
            (`list_and (Ls.map parse_expr args))
      | Sx.List ((Sx.Atom "or") :: args) ->
          if args =@= [] then
            fail "'or' expects arguments"
          else
            (`list_or (Ls.map parse_expr args))
      | Sx.List ((Sx.Atom "not") :: args) ->
          (`not (parse_expr (Sx.List args)))
      | Sx.List [(Sx.Atom "matches"); (Sx.Atom field); (Sx.Atom rex)] ->
          (`matches ((Biblio.field_name_of_string field), rex))
      | Sx.List ((Sx.Atom "ids") :: args) ->
          (`ids (atom_list args))
      | Sx.List ((Sx.Atom "tags") :: args) ->
          (`tags (atom_list args))
      | Sx.List [(Sx.Atom "has"); (Sx.Atom field)] ->
          (`has (Biblio.field_name_of_string field))
      | Sx.List ((Sx.List l) :: []) ->
          (parse_expr (Sx.List l))
      | s -> fail (sprintf 
                     "Can't parse expression %s" 
                     (Sx.to_string s))
    in
    let sexp = 
      try Sx.of_string (sprintf "(%s)" str) 
      with Failure msg ->
        raise (Parse_error (sprintf "Request Syntax Error (sexplib): %s" msg))
    in
    (parse_expr sexp)