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的更多相关文章

  1. 前端与编译原理——用JS写一个JS解释器

    说起编译原理,印象往往只停留在本科时那些枯燥的课程和晦涩的概念.作为前端开发者,编译原理似乎离我们很远,对它的理解很可能仅仅局限于"抽象语法树(AST)".但这仅仅是个开头而已.编 ...

  2. 学了编译原理能否用 Java 写一个编译器或解释器?

    16 个回答 默认排序​ RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...

  3. 用C/C++手撕CPlus语言的集成开发环境(1)—— 语言规范 + 词法分析器

    序言 之所以叫做CPlus语言,是因为原本是想起名为CMinus的,结果发现GitHub和Gitee上一堆的CMinus的编译器(想必都是开过编译原理课程并且写了个玩具级的语言编译器的大佬们吧).但是 ...

  4. Knowledge Point 20180303 对比编译器、解释器与Javac编译原理

    编译器与Javac编译原理 在前文我们知道了Java是一种编译语言和解释语言,它的源代码经过编译器Javac编译为能够被JVM识别的二进制语言,然后JVM将其解释为能够被平台识别的机器语言.那么什么是 ...

  5. <编译原理 - 函数绘图语言解释器(1)词法分析器 - python>

    <编译原理 - 函数绘图语言解释器(1)词法分析器 - python> 背景 编译原理上机实现一个对函数绘图语言的解释器 - 用除C外的不同种语言实现 解释器分为三个实现块: 词法分析器: ...

  6. <编译原理 - 函数绘图语言解释器(2)语法分析器 - python>

    <编译原理 - 函数绘图语言解释器(2)语法分析器 - python> 背景 编译原理上机实现一个对函数绘图语言的解释器 - 用除C外的不同种语言实现 设计思路: 设计函数绘图语言的文法, ...

  7. <编译原理 - 函数绘图语言解释器(3)解释器 - python>

    <编译原理 - 函数绘图语言解释器(3)解释器 - python> <编译原理 - 函数绘图语言解释器(2)词法分析器 - python> <编译原理 - 函数绘图语言解 ...

  8. Compiler Theory(编译原理)、词法/语法/AST/中间代码优化在Webshell检测上的应用

    catalog . 引论 . 构建一个编译器的相关科学 . 程序设计语言基础 . 一个简单的语法制导翻译器 . 简单表达式的翻译器(源代码示例) . 词法分析 . 生成中间代码 . 词法分析器的实现 ...

  9. MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义

    编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...

随机推荐

  1. tp3.2 页面Windows正常 linux异常,页面找不到

    这个问题主要是tp3.2 在读取控制器里的方法时,会把方法自动转为小写, 然后去对应view成找html文件,自然找不到. class textController extends ComContro ...

  2. 和他人一起管理GitHub仓库

    和他人一起管理 GitHub 仓库方法 打开一个项目的仓库 同意好之后在项目中要添加 README.md 文件(重要) 要让别人也可以使用 master 主线 在上传代码前,一定要使用 git 指令 ...

  3. 2018-5 - 凉经 - Mozilla Firefox Ltd - 前端工程师

    北京谋智火狐信息技术有限公司(北京市东城区建国门华润大厦 17 层)过去面试的时候感觉电梯好神奇啊!一边的电梯是直达 18 层以上的,我按了 18 层准备到了再往下走一层,一个老司机和我说要做另一边的 ...

  4. JSP———数据交互【1】

    JSP的内置对象 不用声明就可以在JSP页面中使用 request对象 内置对象 request 封装了用户提交的信息,主要用于处理客户端请求 <FORM action="tom.js ...

  5. HTML5——新表单元素 表单属性 语义元素

    表单元素 新的表单元素 datalist——输入域选项列表 keygen——提供一种验证用户的可靠方法 output——不同类型的输出,比如计算或脚本输出 表单属性 <form> / &l ...

  6. 应用安全 - 工具 - 浏览器 - IE浏览器 - 漏洞汇总

    CVE-2014-6332 Date 2014.11 CVE-2016-0189 | MS16-051 Date 2016年初 CVE-2018-8174

  7. 应用安全 - 编程语言漏洞 - PHP语言漏洞汇总

    CVE-2019-11043 Date: 类型: 远程代码执行 前置条件: Nginx + fastcgi + php-fpm 配置文件信息如下: location ~ [^/]\.php(/|$) ...

  8. 【Windows Server存储】windows文件系统

    windows文件系统 弹性文件系统(ReFS) 无检查磁盘,Windows 8或Windows Server 2012以上运行. 参考资料表明,这是一个失败的文件系统,以后将不会商用. 参考资料:h ...

  9. 【Qt开发】解决Qt5.7.0中文显示乱码的问题

    [Qt开发]解决Qt5.7.0中文显示乱码的问题 亲测可用: 乱码主要是编码格式的问题,这里可以通过Edit菜单中选择当前文档的编码方式,选择按照UTF-8格式保存,然后输入对应的中文,保存,然后运行 ...

  10. 解决react项目中跨域和axios封装使用

    最新几天学了一下react,发现了几个问题,估计新入坑的同学们也会遇到,下面我先列出来几点 1.请求跨域问题 2.如何发起请求 3.axios的简单封装 全局安装create-react-app脚手架 ...