从语法OCaml构建函数

时间:2013-01-25 23:51:00

标签: ocaml context-free-grammar

我正在尝试从通用语法构建解析器 但首先我被要求改变语法(A是起始符号):

(A,[(A,[C;B;C]);
    (A,[C]);
    (B,[A]);
    (C,[B])])

看起来像这样的东西:

   (A,
   function
   | A -> [[C;B;C];[C]]
   | B -> [[C]]
   | C -> [[B]])


如何从列表中的信息生成模式匹配器?
模式匹配器(函数|模式| ... |模式)由程序员定义,如何使用具有此结构的列表中的信息动态创建模式匹配器(A,[[C; B; C]; [C ]])::休息?

如果你想看一个更有意义的更大的语法,请看this question

2 个答案:

答案 0 :(得分:1)

您应该查看ocamllexmenhir,它们是为lexing和解析而设计的工具。

答案 1 :(得分:1)

好的,我想我可能会理解你的问题。以函数开头的数据结构是一个函数!在OCaml中,函数是第一类对象,您可以创建新对象,将它们保存在数据结构中,等等。为了保持纯粹,您无法访问函数的文本表示(就像在某些语言中一样),但您仍然可以以有用的方式组合函数。

这是一个很小的例子。函数maketest取值k并返回一个测试k的函数。

# let maketest k = fun x -> x = k;;
val maketest : 'a -> 'a -> bool = <fun>
# let t8 = maketest 8;;
val t8 : int -> bool = <fun>
# t8 3;;
- : bool = false
# t8 8;;
- : bool = true

函数union接受两个测试函数(如maketest生成的函数)并返回一个函数,用于测试两组值的并集:

# let union f g = fun x -> f x || g x;;
val union : ('a -> bool) -> ('a -> bool) -> 'a -> bool = <fun>
# let t812 = union t8 (maketest 12);;
val t812 : int -> bool = <fun>
# t812 8;;
- : bool = true
# t812 12;;
- : bool = true
# t812 14;;
- : bool = false
# 

函数sequence接受两个测试函数(如maketest生成的函数)并测试以依次与两个函数匹配的整数开头的列表。

# let sequence f g = function
  | []|[_] -> false
  | a :: b :: _ -> f a && g b;;
val sequence : ('a -> bool) -> ('a -> bool) -> 'a list -> bool = <fun>
# sequence (maketest 1) (maketest 4) [1;4;7];;
- : bool = true
# sequence (maketest 1) (maketest 4) [1;8;7];;
- : bool = false
# 

我不完全确定,但我认为你被要求为你的语法组件创建类似这些的函数。要从这样的函数中创建解析器,您需要通过输入流跟踪进度。通常的方法是让解析函数返回剩余的(未解析的)流。