[编译原理]用BDD方式开发lisp解释器(编译器)|开发语言java|Groovy|Spock
lisp是一门简单又强大的语言,其语法极其简单:
(+ 1 2 )
上面的意思 是:+是方法或函数,1 ,2 是参数,fn=1+2,即对1,2进行相加求值,结果是:3
双括号用来提醒解释器开始和结束。
之前在iteye写过一篇文章来简单介绍怎么写lisp的解释器:
http://gyc567.iteye.com/blog/2242960
同时也画了一张草图来说明:

因为lexer(词法分析器)主要工作就是把程序的字符串表达式转化为tokens.(Pair),以下是百科对词法分析的说明:
词法分析是编译过程的第一个阶段,是编译的基础。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。
因为lisp的语法极其简单,词法分析可以认为就是把字符串“(+ 1 2 )”转化为Pair对象,这个Pair 有两个属性:first,rest,first用来记录“+”,rest用来记录另一个Pair,如下图:
Pair1 :
first-->"+"
rest-->Pair2
Pair2:
first-->"1"
rest-->"2"
所以这里主要关注parser,parser主要工作是把Pair对象转化为抽象语法树(AST),并对其他求值返回。
好,现在尝试用BDD的方式来开发实现parser的功能。
先写测试用例:
package com.github.eric.camel import spock.lang.Specification /**
* Created by eric567 on 4/4/2016.
*/
class LispSpockTest extends Specification {
def "Caculate"() {
given:"a instance of Lisp,args: 1 2 "
Lisp lisp=new Lisp()
int arg1=1
int arg2=2
when:"invoke lisp method caculate "
int rt=lisp.caculate(arg1,arg2)
then:"return the result :3"
rt==3 } def "Eval"() {
given:"new Lisp instance,Pair1:fisrt-->+,rest-->Pair2;Pair2:first-->1,rest-->2"
Lisp lisp=new Lisp() ValuePair valuePair2=new ValuePair()
valuePair2.first="1"
valuePair2.rest="2"
ValuePair valuePair1=new ValuePair()
valuePair1.first="+"
valuePair1.rest=valuePair2 when:"eval the Pair1"
Object rt=lisp.eval(valuePair1)
then:"the result should be :3 "
Integer.valueOf(rt)==3 }
}
第一个测试用例用来 测试caculate方法,也这里就是简单的相加功能。代码已经说明一切。
第二个测试用来测试eval求值函数。
好,现在写代码通过这两个测试:
package com.github.eric.camel; /**
* Created by eric567 on 3/8/2016.
*/
public class Lisp {
public int caculate(int i, int i1) {
return i+i1;
} public Object eval(ValuePair valuePair)
{
String fn= (String) valuePair.first;
if(fn!=null&&fn.equals("+"))
{
ValuePair args= (ValuePair) valuePair.rest;
int arg1= Integer.valueOf((String) args.first);
int arg2= Integer.valueOf((String) args.rest);
Integer rt=caculate(arg1,arg2);
return rt;
}
return null;
}
} 而Pair对象的代码很简单:
package com.github.eric.camel; /**
* Created by eric567 on 3/8/2016.
*/ public class ValuePair {
Object first;
Object rest; }
好,再次运行测试用例,应该可以出现绿色线条,祝贺你,你已经实现了一个简单的lisp解释器,you got it .cheeers.
[编译原理]用BDD方式开发lisp解释器(编译器)|开发语言java|Groovy|Spock的更多相关文章
- 前端与编译原理——用JS写一个JS解释器
说起编译原理,印象往往只停留在本科时那些枯燥的课程和晦涩的概念.作为前端开发者,编译原理似乎离我们很远,对它的理解很可能仅仅局限于"抽象语法树(AST)".但这仅仅是个开头而已.编 ...
- 学了编译原理能否用 Java 写一个编译器或解释器?
16 个回答 默认排序 RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...
- 用C/C++手撕CPlus语言的集成开发环境(1)—— 语言规范 + 词法分析器
序言 之所以叫做CPlus语言,是因为原本是想起名为CMinus的,结果发现GitHub和Gitee上一堆的CMinus的编译器(想必都是开过编译原理课程并且写了个玩具级的语言编译器的大佬们吧).但是 ...
- Knowledge Point 20180303 对比编译器、解释器与Javac编译原理
编译器与Javac编译原理 在前文我们知道了Java是一种编译语言和解释语言,它的源代码经过编译器Javac编译为能够被JVM识别的二进制语言,然后JVM将其解释为能够被平台识别的机器语言.那么什么是 ...
- <编译原理 - 函数绘图语言解释器(1)词法分析器 - python>
<编译原理 - 函数绘图语言解释器(1)词法分析器 - python> 背景 编译原理上机实现一个对函数绘图语言的解释器 - 用除C外的不同种语言实现 解释器分为三个实现块: 词法分析器: ...
- <编译原理 - 函数绘图语言解释器(2)语法分析器 - python>
<编译原理 - 函数绘图语言解释器(2)语法分析器 - python> 背景 编译原理上机实现一个对函数绘图语言的解释器 - 用除C外的不同种语言实现 设计思路: 设计函数绘图语言的文法, ...
- <编译原理 - 函数绘图语言解释器(3)解释器 - python>
<编译原理 - 函数绘图语言解释器(3)解释器 - python> <编译原理 - 函数绘图语言解释器(2)词法分析器 - python> <编译原理 - 函数绘图语言解 ...
- Compiler Theory(编译原理)、词法/语法/AST/中间代码优化在Webshell检测上的应用
catalog . 引论 . 构建一个编译器的相关科学 . 程序设计语言基础 . 一个简单的语法制导翻译器 . 简单表达式的翻译器(源代码示例) . 词法分析 . 生成中间代码 . 词法分析器的实现 ...
- MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义
编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...
随机推荐
- learning webrtc 使用node.js
第二章 有使用node.js创建静态服务器的步骤 不过不够详细 下面以Windows为例 1.到官方网站下载安装包 然后安装 2.用管理员权限启动命令行 3.命令行窗口执行npm config set ...
- leetcode-easy-array-66 .plus one
mycode 主要在计算商和余数的时候一定要用还没更新的商和余数哦 class Solution(object): def plusOne(self, digits): ""&qu ...
- leetcode-mid- 50. Pow(x,n)-NO
mycode time limited 例如 x=0.00001 n=2147483647 参考: class Solution(object): def myPow(self, x, n): &q ...
- ES6正则拓展
字符串的正则方法 字符串对象共有 4 个方法,可以使用正则表达式:match().replace().search()和split(). ES6 将这 4 个方法,在语言内部全部调用RegExp的实例 ...
- 阶段3 1.Mybatis_07.Mybatis的连接池及事务_1 今日课程内容介绍
- Jmeter之查看结果树
在编写接口测试脚本的时候,需要进行调试和查看结果是否正常的情况,这个时候可以使用查看结果树组件进行. 查看结果树中展示了每一个取样器的结果.请求信息和响应信息,可以查看这些内容去分析脚本是否存在问题. ...
- spotlight监控linux性能
linux性能监控有很多工具,spotlight只是其中一种 目录 1.安装spotlight 2.参数认识 1.安装spotlight spotlight不仅仅只是监控linux,还可以完成数据库以 ...
- kubernets监控
Weave Scope 容器地图 创建 Kubernetes 集群并部署容器化应用只是第一步.一旦集群运行起来,我们需要确保一起正常,所有必要组件就位并各司其职,有足够的资源满足应用的需求.Kub ...
- 【Java安全】关于Java中常用加密/解密方法的实现
安全问题已经成为一个越来越重要的问题,在Java中如何对重要数据进行加密解密是本文的主要内容. 一.常用的加密/解密算法 1.Base64 严格来说Base64并不是一种加密/解密算法,而是一种编码方 ...
- python数据分析入门(一)----安装pandas
打算入坑, python数据分析 , 所以下载了 <利用python数据分析>的电子书, 影印版 , 14年出版的 , 现在有很多工具对不上号, 但是整体思想还是不变的 , 所以准备工作要 ...