lambda - 带有 FParsec 的简单 lambda 演算解析器

标签 lambda f# fparsec

我是 F# 新手,有一个很烦人的问题。我想解析以下语法:

Application := Expression Expression
Expression  := "(" "lambda" Name "." Application ")"
             | Name
Name        := [a-z]+

这将匹配 (lambda x. (lambda y. x y)) z 之类的东西和 (lambda x. x) y .

我的问题是两个规则相互依赖:
let popen = pchar '('
let pclose = pchar ')'
let pname = many1 letter |>> Seq.toArray |>> System.String |>> NameNode
let plambda = pstring "lambda"
let pdot = pchar '.'
let phead = plambda >>. pname .>> pdot
let pexpression = 
        popen >>. pname .>>. papplication .>> pclose |>> ExpressionNode
    <|> pname
let papplication = pexpression .>>. pexpression
pexpression取决于 papplication和反之亦然。我怎样才能摆脱这种依赖?

最佳答案

递归解析器可以通过 createParserForwardedToRef 实现.这个函数返回一对解析器“句柄”,可以这么说,以及一个包含解析器实现的可变单元格。 “句柄”一旦被调用来实际解析某些东西,就会将调用转发给实现。

获得这对之后,就可以使用“句柄”来实现递归的另一部分,然后创建转发的解析器的实现并将其分配给可变单元格。

let pexpression, pexpressionImpl = createParserForwardedToRef()
let papplication = pexpression .>>. pexpression
pexpressionImpl := 
       popen >>. pname .>>. papplication .>> pclose |>> ExpressionNode
   <|> pname

关于lambda - 带有 FParsec 的简单 lambda 演算解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44350087/

相关文章:

F# 运算符重载之谜

f# - 任何不制作记录值类型的理由

f# - 如果 "till"解析器以空格开头,为什么 manyCharsTill 组合器不起作用?

f# - Fparsec v. 0.9.2(新手)中的空白在哪里?

c# - 使用 NUnit 断言集合中的所有项目都具有其中一个项目属性的值

c++ - FastDelegate 和 lambdas - 无法让它们工作(Don Clugston 最快的委托(delegate))

asynchronous - 具有异步操作的面向铁路的编程

c++ - Lambda 表达式在 if 语句中返回 bool

linq - 使用 LINQ 左连接

parsing - FParsec 和 pipeline3 使参数显式或添加类型符号