我需要使用ocaml处理来自stdin的用户输入。用户将输入命令,直到他键入退出然后程序结束。这该怎么做?我知道如何编写命令,但我想学习功能。用户应该根据他的命令操纵堆栈中的数据。另外,我想像解析器一样处理用户命令。
真的很感谢你的帮助!
答案 0 :(得分:1)
以下是使用OCaml堆栈库编写的内容草图。它远非完美,可以通过多种方式进行改进,但总体结构就在这里。
就您的问题而言,最重要的部分是loop
功能。它从标准输入读取一行,并使用模式匹配来结束程序,或者评估给定和命令,并递归调用自己等待另一个命令。
eval
函数使用给定参数上的模式匹配来做正确的事情。您可以找到Stack
模块here的文档。
let stack = Stack.create ()
let eval args =
match args with
| ["push"; v] -> Stack.push v stack
| ["pop"] -> begin try print_endline (Stack.pop stack) with
| Stack.Empty -> print_endline "Stack is empty"
end
| ["show"] -> Stack.iter print_endline stack
| _ -> print_endline "Unrecognized command"
let rec loop () =
match read_line () with
| "quit" -> print_endline "Bye"
| _ as command -> eval (String.split_on_char ' ' command); loop ()
let () =
loop ()
注意:我通常不喜欢为一个没有展示大量研究的问题提供完整解决方案,但是嘿,你必须要开始在你熟悉函数式编程时的某个地方。
注意2 :此代码仅适用于string
堆栈。如果您打算存储其他类型,例如int
s,或者您希望它是多态的,那么您需要稍微调整一下这些代码。
编辑:根据评论中的评论,下面是上述代码的改进版本,它不使用全局变量堆栈。
let eval s args =
match args with
| ["push"; v] -> Stack.push v s
| ["pop"] -> begin try print_endline (Stack.pop s) with
| Stack.Empty -> print_endline "Stack is empty"
end
| ["show"] -> Stack.iter print_endline s
| _ -> print_endline "Unrecognized command"
let rec loop s =
match read_line () with
| "quit" -> print_endline "Bye"
| _ as command -> eval s (String.split_on_char ' ' command); loop s
let () =
loop (Stack.create ())