1. 解释语言的语言学习
抽象地说,开始设计一门新语言时,咱们须要对这门语言进行描述,描述的主要目的在于告诉使用者如何根据一系列规则来理解使用该语言获得一系列结果(即语言的语义)。flex
这个【描述】所使用的媒介,是一个用来解释语言的语言,或者称为meta-language(元语言)。而使用meta-language来描述新语言的过程,就是实现这门新语言的解释器的过程。spa
举个例子,如同天然语言的语法同样,一我的学习一门天然语言的过程,其实就是在脑中构造一个这门语言的解释器,而这个解释器就是这门语言的语法集合。而这些语法,就是描述这门语言的语言(人类在婴儿时期没有任何语言基础的状况下一步一步构建母语的解释的过程真的美妙 :p )。 设计
可是和天然语言不一样的是,天然语言相对的宽松语法,形成不少场景下的多义性(同时也产生了天然语言所特有的朦胧的美感 :p )。而程序语言的严谨性,要求使用一个可以形式化的meta-language来进行构造,程序语言须要严格地验证其一些性质,以此保证其可执行性和准确性(你大概不会喜欢一个按本身心情返回不一样结果的系统)。orm
2. 对 PL meta-language 的建模递归
工欲善其事,必先利其器。设计一门语言的开始,咱们得先对meta-language进行建模。ip
考虑一下,咱们须要什么?1.表达式,2.求值规则。element
1 告诉咱们若是有一个表达式 B ,那么B属不属于这个语言的表达式范畴。2 则告诉咱们表达式 B 的求值过程。get
咱们发现使用集合[2]很适合用来对咱们设想的meta-language进行建模。具体过程以下:it
对于1,经过定义包含递归结构的BNF[3]表示表达式集合。咱们如今想设计一个能表示OR运算的语言,其能表示嵌套的or运算。其BNF表示以下:
B = t | f | ( B . B )
"." 表示或运算符,上面的这个BNF表示肯定了表达式集合B,前两项 t (true) 和 f(false) 称为终结项( 我的更倾向于叫原子项 ),由于这两项是在上述的定义中最基本不可再分的元素;这个集合中的元素有:B = { t , f , (t.f) , (t.( f . t)) .... }。由于咱们在上面的第三项加入了一个递归定义,因此这个集合如今包含了嵌套的表达式而不只仅是简单的 t 或者 f 。
对于 2,使用 relation 来对求值过程进行构建,在构建以前,先说明一下relation一些后面将用到的性质。
- relation 是一个有序对 ( ordered pair ) 集合 ( A relation is a set whose element is ordered pair) ,若是有关系 r 使得 a r b 且 c r d , 那么 r 就是有序对集合: r = {<a,b>,<c,d>}
- 对于任意x,有<x,x>∈ r ,则称关系 r 具备自反性(reflexive)
- 对于任意<x,y>∈ r ,<y,z>∈ r,有 <x,z>∈ r ,则称关系 r 具备传递性(transitive)
- 对于任意<x,y>∈ r ,有<y,x>∈ r ,则称关系 r 具备对称性(symmetric)
- 若是关系 r 同时具有自反性,传递性,对称性,则称其为等价关系
使用关系 r 与等价关系关系 rt 建模,能够获得下面的OR求值规则:
- ( t . B ) r t
- ( f . B ) r B
- B r B' → B rt B'
- B rt B
- B1 rt B2 → B2 rt B1
- B1 rt B2 且 B2 rt B3 → B1 r t B3
关系 rt 描述了求值的过程,所以咱们把关系 rt 称为求值关系。如今咱们能够利用上面的规则来对一些表示式进行求值。好比对 ( f. (f . t) ) 进行求值:
f ∈ B , t ∈ B → ( f . t ) ∈ B
( f . t ) ∈ B , ( t . B ) rt t → ( f. (f . t) ) rt ( f . t )
t ∈ B ,( f . B ) rt B → t
上面的这一个过程称为规约(reduction)。看起来很不错,再让咱们尝试着使用上面的定义对表达式 ( (f . t) . f ) 进行求值。
发现问题了吗?上面的规则没法对( (f . t) . f ) 进行求值,可能你一眼就能看出结果为 t ,可是咱们的定义没法推导出来。为何?由于 f 放到了表达式的后面,这个表达式明显应该被理解为 ( B . f ) ,可是对于 ( B . f )而言, 咱们的求值关系没有诸如 ( B . f ) r B 的规约规则。
这时候须要扩充求值关系 r :
- B1 r B2 → B1 rc B2
- B rc B' → ( B . B1 ) rc ( B' . B1 )
通过扩展的关系 rc 称为compatible clojure(这个概念在大多数地方没法查到)。
增长自反-传递性:
- B1 rc B2 → B1 rrt B2
- B rrt B → ( B . B1 ) rc ( B' . B1 )
- B1 rrt B2 且 B2 rrt B3 → B1 rrt B3
增长对称性:
- B1 rrt B2 → B1 re B2
- B1 re B2 → B2 re B1
最终扩展获得的关系 re 称为关系 r 的 reduction relation。
上面以描述OR运算过程做为例子,引入了集合语言来对语言进行描述,固然即使是设计一个最简单的语言,所须要的还不只仅是上述这些内容。篇幅局限,先记录到这里。
3. 参考文献