在程序中使用ocaml Args

时间:2013-09-09 18:48:35

标签: parsing ocaml

我正在尝试创建一个ocaml程序,用户输入类似于命令行参数的输入,例如......

./program
$ -s foo -i 84
$ -s bar -i 22

...基本上是一个简单的菜单程序。

我希望能够使用ocaml Args来执行此操作(特别是内置'使用'等),但我意识到这仅适用于命令行。有没有办法重新使用这个库来为程序内用户输入工作,或者最好是从Stream/Parser库或完全不同的解决方案一起破解某些东西?

2 个答案:

答案 0 :(得分:4)

(请注意,模块名称为Arg,而不是Args。)

如果你愿意编写代码来将这一行分解为单词,那么函数Arg.parse_argv似乎完全符合你的要求。

(请注意,在类Unix系统中,它是shell,而不是Arg模块,它将行分为单词。所以要以这种方式使用Arg,你必须做shell所做的事情。)

答案 1 :(得分:3)

感谢Jeffrey正确的API调用...最初,我无法弄清楚如何多次使用该调用(因为值将设置为您给出的第一个集合),以及技巧是否必须使用可选参数?current:(Some (ref 0))多次使用该调用。

这是我的代码,如果它可以帮助其他人(注意我没有检查错误等):

(* default values *)
let somestr = ref ""
let someint = ref 0
let usage = "usage: set [-s string] [-d int]"

(* from http://rosettacode.org/wiki/Command-line_arguments#OCaml *)
let speclist = [
    ("-s", Arg.String (fun s -> somestr := s), ": follows -s sets some string");
    ("-d", Arg.Int    (fun d -> someint := d), ": some int parameter");
  ]

let parseinput userinp =
  (* Read the arguments *)
  Printf.printf "String:%s\n" (Array.get userinp 2);
  Arg.parse_argv ?current:(Some (ref 0)) userinp
    speclist
    (fun x -> raise (Arg.Bad ("Bad argument : " ^ x)))
    usage;
  Printf.printf "Set stuff to:   %d '%s'\n%!"  !someint !somestr 

let  parseit line =
  Printf.printf "processing %s%!\n" line;
  (* TODO rewrite without Str*)
  let listl = (Str.split (Str.regexp " ") line) in
  parseinput (Array.of_list listl)

let _ =
try
  while true do
    let line = input_line stdin in
    parseit line
  done;
  None
with
  End_of_file -> None

编译:

ocamlc str.cma -o args args.ml

提供它的命令:

set -d 8332 -s lalalla
set -d 11111 -s fffffff