【TAPL学习笔记 2】An ML Implementation of Arithmetic Expressions


我们在这章主要使用OCaml来进行代码实现。

4.1 Syntax

我们的第一个工作是定义term。

type term = 
	TmTrue of info
	| TmFalse of info
	| TmIf of info * term * term * term
	| TmZero of info
	| TmSucc of info * term
	| TmPred of info * term
	| TmIsZero of info * term

构造子TmTrue到TmIsZero命名了抽象语法书的不同类型节点,of后面的类型指定了子树的个数。

每个抽象语法树节点都被注解为一个类型info的值,它用来向用户展示哪里出现错误。为了理解求值以及类型检查的基本算法,这个信息可以直接被忽略。
在求值关系的定义中,我们需要检查一个term是否为数值。

let rec isnumericval t = match t with 
	TmZero(_) ->true
	| TmSucc(_,t1) -> isnumericval t1
	| _ -> false

这是在OCaml中通过模式匹配定义递归函数的典型例子。
检查一个term是否为value的函数如下:

let rec isval t = match t with
	TmTrue(_) -> true
	| TmFalse(_) -> true
	| t when isnumericval t -> true
	| _ -> false

其中第三个条款是条件模式:匹配任何term t,但只有当布尔表达式输出true的时候。

4.2 求值

我们在这里直接定义异常,如果没有求值规则能应用。

exception NoRuleApplies

let rec eval1 t = match t with
	TmIf(_,TmTrue(_),t2,t3) -> t2
	| TmIf(_,TmFalse(_),t2,t3) -> t3
	| TmIf(fi, t1,t2,t3) -> 
		let t1' = eval t1 in 
		TmIf(fi,t1',t2,t3)
	| TmSucc(fi,t1) ->
		let t1' = eval1 t1 in
		TmSucc(fi, t1')
	| TmPred(_, TmZero(_)) ->
		TmZero(dummyinfo)
	| TmPred(_,TmSucc(_,nv1)) when (isnumericval nv1) →
		nv1
	| TmPred(fi,t1) →
		let t1’ = eval1 t1 in
		TmPred(fi, t1’)
	| TmIsZero(_,TmZero(_)) →
		TmTrue(dummyinfo)
	| TmIsZero(_,TmSucc(_,nv1)) when (isnumericval nv1) →
		TmFalse(dummyinfo)
	| TmIsZero(fi,t1) →
		let t1’ = eval1 t1 in
		TmIsZero(fi, t1’)
	| _ →
		raise NoRuleApplies

我们可以定义一个求值函数

let rec eval t = 
	try let t' = eval1 t
		in eval t'
	with NoRuleApplied -> t

4.3 The rest of the story

下图为解释器的处理流程:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值