我正在尝试为处理lambda演算的语言编写一个小编译器。以下是我发现的语言含糊不清的定义:
E → ^ v . E | E E | ( E ) | v
符号^,。,(,)和v是标记。 ^表示lambda,v表示变量。 形式^ v.E的表达式是函数定义,其中v是函数的形式参数,E是其主体。如果f和g是lambda表达式,那么lambda表达式fg表示将函数f应用于参数g。
我试图为这种语言编写一个明确的语法,假设函数应用程序是左关联的,例如fgh =(fg)h,并且该函数应用程序绑定比...更紧密,例如,(^ x。^ y.xy)^ zz =(^ x。(^ y.xy))^ zz
这是我到目前为止所做的,但我不确定它是否正确:
E -> ^v.E | T
T -> vF | (E) E
F -> v | epsilon
有人可以帮忙吗?
答案 0 :(得分:6)
在阅读你的问题和评论之间,你似乎更多地寻求学习和实施lambda演算的帮助,而不仅仅是你在这里提出的具体问题。如果是这样,那么我在同一条路上,所以我将分享一些有用的信息。
我所拥有的最好的书,也就是最好的书,不是说本杰明·皮尔斯Types and Programming Languages(WorldCat)。我知道标题听起来不像lambda演算,但看看λ-Calculus extensions: meaning of extension symbols列出了本书中的许多lambda演算。 OCaml和F#中有该书的代码。
尝试在CiteSeerX中搜索关于lambda演算的研究论文以了解更多信息。
到目前为止,我发现的最佳λ微积分评估器是:
Lambda calculus reduction workbench信息here。
另外,我发现你在CS:StackExchange编程时遇到的lambda演算问题和Math:StackExcahnge的数学相关问题得到了更好的答案。
对于实现lambda演算的编程语言,如果你没有,你可能需要学习functional language;是的,这是一个不同的野兽,但在山的另一边的启蒙是壮观的。我找到的大多数源代码都使用了ML或OCaml这样的函数式语言,一旦你学会了它,其余的就会更容易学习。
更具体地说,here是无类型lambda演算项目的源代码,here是YACC的F#变体的输入文件,从阅读之前的questions看来在你的知识世界中,here是样本输入。
由于语法是用于实现REPL,因此它以toplevel,think命令提示符开头,并接受多个命令,在本例中是lambda演算表达式。由于这种语法用于许多计算,因此在前面的例子中它具有占位符的部分,因此这里的绑定更像是一个占位符。
最后我们到达你所追求的部分
注意LCID是小写标识符
Term : AppTerm
| LAMBDA LCID DOT Term
| LAMBDA USCORE DOT Term
AppTerm : ATerm
| AppTerm ATerm
/* Atomic terms are ones that never require extra parentheses */
ATerm : LPAREN Term RPAREN
| LCID
答案 1 :(得分:2)
你可以在次线性时间内找到特定语法模糊性的证明,但证明语法是明确的是NP完全问题。您必须使用该语言生成每个可能的句子,并检查每个句子只有一个派生。