1

我正在编写一个程序,它解析用某种虚构语言编写的脚本并使用该脚本进行一些计算。这种语言有一个特殊的结构,用于调用 类型的外部 OCaml 函数'a -> bool。所以,在我们可能拥有的语言中间

blah blah function (foo 45) blah blah

我希望解析器使用构造函数,例如

OCamlFunction of ('a -> bool) * 'a

将该位解析为值

OCamlFunction (foo,45)

其中“foo”是用户必须在单独的 .ml 文件中提供的函数,解析器事先不知道该函数;只有定义了“foo”的 OCaml 文件的名称才会在运行时传递给解析器。因此,我需要定义一个 string-> 类型的函数,('a->bool)它采用某个函数的名称并返回该函数。

我的问题是:

(1) 我假设代码的动态加载应该使用DynLink.loadfile。这是要走的路吗?

(2) 如何从函数“foo”的标识符中访问函数?(这会带我去camlp5吗?)

4

2 回答 2

2

您不能直接按名称加载函数,因为 OCaml 没有这种支持,并且该loadfile函数只是运行代码,它不提供对名称的访问。

您需要在加载的代码使用的主程序中支持某种功能注册 API。所以加载的代码会做类似的事情

ParserEngine.register_function "foo" foo_impl

您可以使用 Camlp{4,5} 自动生成此样板代码,或者您可以register_functions使用关联列表进行调用以将其最小化。

register_functions然后会将函数存储在一些内部结构中,例如哈希表或可变关联列表,以供您的解析器代码访问。

于 2011-03-11T01:03:52.407 回答
2

另一种解决方案是将整个脚本放在引号中,并将每个 ocaml 值放在反引号中。例如,这可以使用 Camlp4 来完成,但有一点语法成本(<< >>围绕您的代码,$ $围绕 OCaml 值)。然后脚本的解析将在编译时运行,因此 OCaml 类型器本身可以检查您引用的 OCaml 值是否也已明确定义。此外,您可以获得更精细的类型控制。

于 2011-03-11T06:02:45.233 回答