如何使用纯函数式编程在ocaml中创建非上下文分析器?

时间:2019-04-08 23:44:22

标签: parsing functional-programming ocaml

我正在尝试使用OCaml中的纯函数编程来创建非上下文分析器。该函数将采用字符串列表,如果遵循(a ^ xb ^ yc ^ zd ^ k)的格式,则返回true,这意味着列表需要包含“ a”,“ b”的任何数字(大于0)。 ,“ c”和“ d”。

我建议我尝试创建一组相互递归的函数,但是我一直在努力寻找成功完成此任务的方法。

以下是该函数的一些输入和输出示例:

# string(["a";"b";"c";"d"]);;
- : bool = true

# string(["a";"a";"b";"c";"c";"c";"d"]);;
- : bool = true

# string(["a";"c";"d";"d"]);;
- : bool = false

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:2)

使某些功能完全起作用的关键是必须将所有状态作为函数参数和返回值传递。在您的情况下,状态为输入流;即尚未解析的列表。

一种实现方法是让每个解析函数返回一个布尔值,说明是否看到了预期的结果,还返回列表中未解析的其余部分。

这意味着您将使用具有以下类型的解析函数:

aplus : string list -> bool * string list
bplus : string list -> bool * string list

如果您只想查找a,然后是b,则可以这样编码:

let parse strings =
    let (good, rest) = aplus strings in
    if not good then false
    else let (good, rest) = bplus rest in
    good && rest = []

这是非常麻烦的代码。如果您有一个功能类似于“ &&”的函数,那可能会更整齐,只是它会将未解析的列表传递给下一个函数。当您开始编写纯功能代码时,经常会出现这种情况。

还有许多其他方法可以构成解析结构,其中一些方法可能比上述方法更好。但是关键(IMHO)是您的解析函数需要返回输入流的其余部分以及成功/失败指示。

(请注意,这里还没有递归,但是当您编写各个解析函数时会出现这种情况。)