我正在OCaml中实现一种简单的类似于C的语言,并且像往常一样,AST是我的中间代码表示形式。由于我将在树上进行很多遍历,因此我想实现一种访问者模式以减轻痛苦。我的AST目前遵循该语言的语义:
type expr = Plus of string*expr*expr | Int of int | ...
type command = While of boolexpr*block | Assign of ...
type block = Commands of command list
...
现在的问题是树中的节点具有不同的类型。理想情况下,我将把处理节点的单个函数传递给访问过程。该过程将打开节点的类型并进行相应的工作。现在,我必须为每个节点类型传递一个函数,这似乎不是最佳解决方案。
在我看来,我可以(1)真正采用这种方法,或者(2)在上面仅使用一种类型。解决此问题的通常方法是什么?也许使用OO?
没有人在功能语言中使用访客模式-这是一件好事。使用模式匹配,幸运的是,仅使用(相互)递归函数,您就可以更轻松,直接地实现相同的逻辑。
例如,假设您想为AST编写一个简单的解释器:
let rec run_expr = function
| Plus(_, e1, e2) -> run_expr e1 + run_expr e2
| Int(i) -> i
| ...
and run_command = function
| While(e, b) as c -> if run_expr e <> 0 then (run_block b; run_command c)
| Assign ...
and run_block = function
| Commands(cs) = List.iter run_command cs
访问者模式通常只会使这一点复杂化,尤其是当结果类型是异构的时,例如此处。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句