编程语言分析及其应用:Lisp格式到C格式的转换及其计算

来源:互联网 发布:旅行的意义 知乎 编辑:程序博客网 时间:2024/06/02 02:14

  • Lisp格式到C格式的转换
  • Lisp格式表达式的类型检测
  • Lisp格式表达式的计算

Lisp格式到C格式的转换

  • Lisp的函数调用格式为: (函数名 参数1 参数2 … 参数n)
  • C的函数调用格式为:函数名(参数1, 参数2, …, 参数n)
  • 现有五个整数的二元函数add、sub、mul、div、mod和一些使用这些函数的Lisp格式表达式,请实现一个程序转换器,将这些Lisp格式表达式转成C格式的表达式,如下表。
    Lisp格式表达式转成C格式的表达式的示例

首先考虑的是,需要将操作符(add等)和操作数(1,2…)得到。
先把表达式两端无用括号去掉,然后以空格分隔成数组,并且记录(和)的个数来判断当前是否为一个完整的操作数(可能是单独的一个数或一个完整的表达式如 ( add 1 1 ))。

def split_s(ss):    pass'''add 1 1 => ["add", "1", "1"]add ( add 1 1 ) ( sub 1 5 )  => ["add", "( add 1 1 )", "( sub 1 5 )"]add ( add 1 1 ) ( sub 1 5 ) ( mul 1 2 3 )=> ["add", "( add 1 1 )", "( sub 1 5 )", "( mul 1 5 )"]'''

接下来只要递归处理获得单个操作符和单个操作数即可。
没错就是递归。

# lisp 转 cdef to_c(ss):    pass'''add 1 2 => add(1,2)add ( add 1 1 ) ( sub 1 5 )  => add(add(1,1),sub(1,5))add ( sub 4 2 ) ( div 2 3 ) ( mul 10 1 ) ( add 1 1 2 ) 1 => add(sub(4,2),div(2,3),mul(10,1),add(1,1,2),1)'''

Lisp格式表达式的类型检测

  • Lisp的函数调用格式为: (函数名 参数1 参数2 … 参数n)
  • 现有两个类型:整数int和布尔类型bool,以及五个整数的二元函数add、sub、gt、lt、equ和三个布尔值的函数and、or、not,其类型检测规则如下:
    Lisp格式表达式的类型检测规则
  • 请实现一个类型检测器,并检测这些Lisp格式表达式
    大致思路就是将“+-*”结果记为0,“/%”结果记为1,剩余操作记为“T”表示bool类型。每次运算需先判断是否类型匹配,且“/%”还需额外判断除第一个数其余数非0。判断类型匹配用到了reduce处理。

这里需要用到上述得到操作符和操作数的方法,然后将每个操作数做类型映射,比如可以把所有的int转0,bool转true等,然后依次累加啊处理啊,就可以了。注意的是还要关注除法和%操作第二个操作数不能为0,就搞定啦。可以考虑用py的map和reduce来简化处理。

from functools import reduce# 判断是否为bool类型def is_bool(ss):    return ss in ["T", "F"]# Lisp格式表达式的类型检测def check(ss):    pass

Lisp格式表达式的计算

  • Lisp的函数调用格式为: (函数名 参数1 参数2 … 参数n)
  • 现有五个整数的二元函数add、sub、mul、div、mod,其语义计算规则如下
    Lisp格式表达式的计算
  • 请实现一个计算器,计算这些Lisp格式表达式

做完类型检测,处理计算就容易多了,没什么问题。

# 表达式计算,需先进行check()类型检测def cal(ss):    pass'''( add 1 2 ) => 3( add ( add 1 1 ) ( sub 1 5 ) ) => -2( add ( sub 4 2 ) ( div 2 3 ) ( mul 10 1 ) ( add 1 1 2 ) 1 ) => 23( add ( sub 4 2 ) ( div 2 3 ) ( mul 10 1 ) ( add 1 e 2 ) 1 ) => e'''

思想都摆在上边,最后实现的是支持多个参数的转换器和计算器。
pass有需要的可以自己YY填空,渡过安全期再补上,渡劫渡劫… =。=

实验要求

原创粉丝点击