因为 这篇 blog 里面记载的原因 突然就对 λ 演算有一点点兴趣,于是写了一个 λ 项的解析器。
作为一个理论计算机科学学生,我比较喜欢 neat 的设定,为了最简化问题,采用 de Bruijn 下标记法,使用无类型的 λ 演算,并且不允许自由变量。
词法:
lambda
单词是 lambda
这个串,或者 .
(句点);var
单词是一个不超过 65536 的正整数;const
单词是一个标识符(选的字符集比较怪,细节没什么可说的);(
单词和 )
单词就是 (
和 )
。语法:
Term
产生;Term
可以变成 List Abs
或者 List App
;List
可以变成 List App
或者 空白;Abs
可以变成 lambda Term
;App
可以变成 var
、const
或者 ( Term )
。语义(如何联系到普通的记法):
var
都不能超过它具有的 Abs
祖先的个数。(不允许自由变量)var
的面值决定了它表示的变量是被它祖上第 面值 近的 Abs
祖先捕获的变量。const
的字面量通常来说是一个字典里面的 entry,这样在书写的时候会简单一些,和文字替换是一样的效果(外面可能需要加括号),具体字典有哪些 entry 由 parser 的消费者决定。λx.λy.xy
的写法是 lambda lambda 2 1
或者更简单的是 ..2 1
。目前只写了解析器(从头开始手写的~包括自己的内存池、引用计数指针、CRTP 模板、自己的词法器、语法器,这个语法太简单了,所以手写比较容易),