【发布时间】:2015-02-11 06:09:01
【问题描述】:
是否可以在 F# 中为引用定义自定义解析器和 AST?具体代码
open Microsoft.FSharp.Quotations
let e = <@ 1+1 @>
生成
val e : Expr<int> = Call (None, op_Addition, [Value (1), Value (1)])
我想做两件事。一,我想生成自己的 AST。例如
val it : Expr = Add(Num 1,Num 1)
二,我想定义自己的解析器,而不是使用 F# 语法。例如,写一些类似的东西会很好
let e = <@ 1++1 @>
当然,如果我不关心语法,我可以定义一个从 F# 语法树到我自己的语法树的程序转换。我不想那样做;我想使用自定义解析器。
对于某些背景,我想使用引号和反引号来为某些 DSL 生成 AST。基本上,我想要以下内容
let e1 = <@ 1 @>
let e2 = <@ %e1 + 2 @>
生成Add(Num 1,Num 2),不要受制于 F# 语法。
顺便说一句,虽然现在是一种非常不同的语言,但在带有camlp4的OCaml中上述是可能的,所以这似乎是可行的,但我不确定是否有任何F#限制阻止了这一点。
编辑 1
@tomas-petricek 回答了我的直接问题,但我正在寻找的更符合@mydogisbox。看起来嵌入式语言在 F# 中的完成方式与在 OCaml 或 Haskell 中不同,我不知道。感谢您的提示。
【问题讨论】:
-
F# 是一种支持图灵的编程语言。您在其中构建一个解析器,用于任何可合理解析的内容。您是要我们为您构建解析器吗?
-
当然,我可以定义一些读取字符串的函数,并且主要执行我想要生成 AST 的操作。但是,将反引号放入其中是一件很痛苦的事情。最直接的方法是像 printf 一样,我们有特殊的标签 %d 和 %f,但是参数与占位符分开。由于 F# 已经有报价系统,我想使用它而不是重新发明轮子。
-
你问是否可以写一个解析器。这是。这里还有什么可做的?反引号只是更多的语法;为什么这是一个问题?也许你的意思是,“有可能编写一个与 F# 语法挂钩的解析器”?我不知道。也许您坚持让您的解析器使用 F#(解析)机器进行反引号;这似乎很难,因为没有理由相信它会与您构建的解析器很好地集成。
-
上面的具体问题不是是否可以生成解析器,而是是否可以将自定义解析器集成到F#的报价系统中。由于许多原因,这是一件常见的事情并且很有用。在 OCaml 中,这是通过camlp4 和语法
let foo = <myexpr:< parsers + are + $e$ >>完成的。在 Haskell 中,这是通过 Template Haskell 和语法let foo = [myexpr| parsers + are + $e |]完成的。好的报价工具为开发人员提供位置信息等信息,以提供合理的错误(calmp4 中的 _loc)。这已经完成了。