AST with Scope
AST是用来表示语法构造的数据结构,而在大多数语言中都有“变量”的概念。 那么应在AST中用什么方式表示一个“变量”呢? 怎么进行变量的替换呢? 怎么进行变量作用域的检查呢? First-Order Abstract Syntax 最简单直接的方法就是直接用字符串保存变量名,以lambda calculus为例: type Name = String data Expr = Var Name | App Expr Expr | Lam Name Expr 这种AST被称为FOAS,一般是parse完得到的。但这种裸的AST几乎不包含任何信息,变量和作用域之间没有直接的关系,bindings也只是由匹配字符串来表示。 在这个层面上对AST操作是十分不安全的,稍不注意就可能改变了语义。比如说不带更名的substitution:(λy.λx.y)x→λx.x。 若要写出正确的substitution还得花点小心思,这是wiki上lambda calculus的substitution的定义(少了一种情况): x[x := N] ≡ N y[x := N] ≡ y, if x ≠ y (M1 M2)[x := N] ≡ (M1[x := N]) (M2[x := N]) (λx.M)[x := N] ≡ λx.M (λy.M)[x := N] ≡ λy.(M[x := N]), if x ≠ y, provided y ∉ FV(N) “翻译到”haskell:...