I wrote a blog post Recipes for OCamlLex. Edit: and here is a sketch. The idea is to use a scanner to split a string into a list of words. It would now be easy to add special cases, for example for common abbreviations. The file below is camel.mll for OCamlLex.
{
exception Error of string
let error fmt = Printf.kprintf (fun msg -> raise (Error msg)) fmt
let get = Lexing.lexeme
}
let digit = ['0'-'9']
let lower = ['a'-'z']
let upper = ['A'-'Z']
let punct = ['_']
rule split = parse
| upper+ (lower|digit)* { let word = get lexbuf in word :: split lexbuf }
| eof { [] }
| _ { get lexbuf |> error "illegal character '%s'" }
{
let snake_case str =
Lexing.from_string str
|> split
|> ( function
| [] -> []
| x::xs -> x :: List.map String.lowercase_ascii xs
)
|> String.concat "_"
let main () =
Array.to_list Sys.argv
|> List.tl
|> List.map snake_case
|> List.iter print_endline
let () = main (); exit 0
}
$ ./_build/default/camel.exe PollFD DoubleIEEE754 MemVTable
Poll_fd
Double_ieee754
Mem_vtable