let lexer s =
  let ops = Hashtbl.create 10 in
  Hashtbl.add ops '+' (Op Add);
  Hashtbl.add ops '-' (Op Sub); 
  Hashtbl.add ops '*' (Op Mul);
  Hashtbl.add ops '/' (Op Div); 
  
  let n = String.length s in
  
  let rec read i ilast =
    if (i = n || Hashtbl.mem ops s.[i]) && (i <> ilast) then
      Val (float_of_string (String.sub s ilast (i-ilast)))
        ::(if i=n then [] else read i i)
    else if Hashtbl.mem ops s.[i] then Hashtbl.find ops s.[i]
                                         ::read (i+1) (i+1)
    else read (i+1) ilast
  in read 0 0