以鶸ice为例,手撸一个解释器(一)明确目标
# HelloWorld.ice
print("hello, world")
前言(废话)
其实从开始学习编译原理到现在已经有快半年的时间了,但是其间常常不能坚持看下去龙书(经常三天打鱼两天晒网,更何况每次打鱼不到半小时就累得不行又会放下书(笑)),截至到现在只勉强看完了前六章的部分,半年间其它事也没有做,其实想想上大学已经快两年了还是一事无成,知识也没有学到,不免觉得很羞愧。
暑假也要到了,这个学期马上也要结束了,临近大二结束之际,还是尝试着写一下以前想写的玩具吧,而本系列就是对这段过程的记录,也算是对龙书前六部分的一个小实践&总结(后面的部分可能看完了我也写不出什么东西来)。
其实再写这个解释器之前,我是拿lex + yacc + llvm照着tutorial试着拼过一个编译器,但是llvm对我来说可能有些太难了(苦笑)。残破不堪的代码在lyli分支上。
这个系列的教程(如果可以算作教程的话),其实主要还是实现了前端部分(一样有很多bug),而parser早就被研究透了,所以本教程基本上没有什么价值,可能唯一具有优势的地方就是我跟愿意看这几篇文章的读者大概是相同的入门(或者还未入门)的水平。
本教程分为四章
- 明确目标 & 设计语言
- 实现词法分析器
- 实现语法分析器
- 实现基础数据类型
且希望能达到在读者阅读完本系列后,能完成一个支持以下几项的解释器语言
- 整型、浮点型以及字符串类型
- 常见双目运算符
- 变量定义
- 函数定义及调用
- 基本控制流语句
- lambda表达式
适合读者
- 对编译原理感兴趣,但是还尚未正式的开始学习
- 尝试完成一个玩具解释器但不知道如何下手
正文
在正式手撸之前,我们要先确立我们要撸的是个什么玩意儿(你这不是废话吗摔)。毕竟在后期想要增加一些新的骚操作(新特性)的时候,若没有在一开始进行设计,难免会出现各种重构上令人烦躁的问题(虽然如果你按照本教程撸出来的解释器必然会带来重构上各种糟糕的问题,但是重构本身就是一件会带来各种糟糕的问题的事情(所以就不要介意了)),但是在正式写代码之前进行设计,总是一件应该做的事。
解释什么
从解释器角度来说,我们解释的是字符串,在验证字符串满足规则后进行解释,在解释完之后将其按照语义正确执行,而这个规则就是我们Ice的语法规则。
从词法分析器的角度来说,我们解释是字符串,只需要输入的字符串满足我们为词素指定的规则,然后根据输入的字符串返回token给语法分析器就可以了。
从语法分析的角度来说,我们解释的是token序列,且通过预测分析法依据token序列选择正确的产生式并返回抽象语法树(Abstract Syntax Tree)。
输入形式
只考虑交互式输入(即一行一行的输入)
如何解释
本项目中主要包含以下几个类:
- Token:实例化的Token对象包含一个词素的类型以及词素值
- LexicalAnalyzer:解析输入字符串,返回token序列
- Node:实例化的Node及其派生类对象包含AST中一个节点所应具有的信息
- SyntaxAnalyzer:根据token序列预测分析,返回AST(实质是一个Node或其派生类实例)
- IceObject:包括自身类型信息,以及实现相关运算
- Env:符号表,存储Ice运行时的对象信息
- Interpreter:只提供run()接口供main函数调用,隐藏内部逻辑
好了,基本上结构就是这样,下面可以着手考虑Ice具备怎么样的语法了。
Ice 语法
整形、浮点型以及字符串类型
1
1.0
"hello, world"
常见双目运算符
1 + 1
(100 + 20) * 6 / 3
10 = 10
5 <= 3
变量定义
@a: 1
函数定义及调用
@add(a, b): a + b
@mul(a, b)
{
return a * b
}
mul(mul(2, 3), add(2, 3))
基本控制流语句
@fib(n)
{
if (n = 0) + (n = 1)
{
return 1
}
else
{
return fib(n-1) + fib(n-2)
}
}
fib(10) # 89
@a: 3
while a
{
print(a)
@a: a - 1
}
@a: 0
do {
@a: a + 1
if a = 3
{
break
}
print(a)
} while a < 5
for 1 to 5
{
@a: a + 1
if a = 3
{
continue
}
print(a)
}
lambda表达式
@add(a, b): a + b
@mul: @(a, b){
return a * b
}
@(a, b){ return a / b }(9, 3)
@quadraticSum: @(a, b){
@sqrt: @(n){ return n * n }
return @(a, b){ return a + b }(sqrt(a), sqrt(b))
}
基本上就是这样,那么如果你还继续打算看的话,下一章将会开始手撸Ice的词法分析器。
以鶸ice为例,手撸一个解释器(一)明确目标的更多相关文章
- 五分钟,手撸一个Spring容器!
大家好,我是老三,Spring是我们最常用的开源框架,经过多年发展,Spring已经发展成枝繁叶茂的大树,让我们难以窥其全貌. 这节,我们回归Spring的本质,五分钟手撸一个Spring容器,揭开S ...
- 使用Java Socket手撸一个http服务器
原文连接:使用Java Socket手撸一个http服务器 作为一个java后端,提供http服务可以说是基本技能之一了,但是你真的了解http协议么?你知道知道如何手撸一个http服务器么?tomc ...
- 【手撸一个ORM】MyOrm的使用说明
[手撸一个ORM]第一步.约定和实体描述 [手撸一个ORM]第二步.封装实体描述和实体属性描述 [手撸一个ORM]第三步.SQL语句构造器和SqlParameter封装 [手撸一个ORM]第四步.Ex ...
- 第二篇-用Flutter手撸一个抖音国内版,看看有多炫
前言 继上一篇使用Flutter开发的抖音国际版 后再次撸一个国内版抖音,大部分功能已完成,主要是Flutter开发APP速度很爽, 先看下图 项目主要结构介绍 这次主要的改动在api.dart 及 ...
- 通过 Netty、ZooKeeper 手撸一个 RPC 服务
说明 项目链接 微服务框架都包括什么? 如何实现 RPC 远程调用? 开源 RPC 框架 限定语言 跨语言 RPC 框架 本地 Docker 搭建 ZooKeeper 下载镜像 启动容器 查看容器日志 ...
- C#基于Mongo的官方驱动手撸一个Super简易版MongoDB-ORM框架
C#基于Mongo的官方驱动手撸一个简易版MongoDB-ORM框架 如题,在GitHub上找了一圈想找一个MongoDB的的ORM框架,未偿所愿,就去翻了翻官网(https://docs.mongo ...
- 手撸一个SpringBoot-Starter
1. 简介 通过了解SpringBoot的原理后,我们可以手撸一个spring-boot-starter来加深理解. 1.1 什么是starter spring官网解释 starters是一组方便的依 ...
- 手撸一个springsecurity,了解一下security原理
手撸一个springsecurity,了解一下security原理 转载自:www.javaman.cn 手撸一个springsecurity,了解一下security原理 今天手撸一个简易版本的sp ...
- Golang:手撸一个支持六种级别的日志库
Golang标准日志库提供的日志输出方法有Print.Fatal.Panic等,没有常见的Debug.Info.Error等日志级别,用起来不太顺手.这篇文章就来手撸一个自己的日志库,可以记录不同级别 ...
随机推荐
- 简单的sdn防火墙
github仓库 演示视频 本次实验建立的拓扑 使用到的 pox 指令介绍,参考pox控制器学习笔记 1. forwarding.l2_learning 使OpenFlow交换机充当L2学习交换机的一 ...
- Go标准库之html/template
html/template包实现了数据驱动的模板,用于生成可防止代码注入的安全的HTML内容.它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用html/templ ...
- 新增访客数量MR统计之NewInstallUserMapper中维度信息准备
关注公众号:分享电脑学习回复"百度云盘" 可以免费获取所有学习文档的代码(不定期更新)云盘目录说明:tools目录是安装包res 目录是每一个课件对应的代码和资源等doc 目录是一 ...
- Win10+Java7环境配置
原文链接: https://www.toutiao.com/i6487838676326810125/ 安装包: jdk-7u79-windows-x64-20151024 打开安装目录 双击运行程序 ...
- 在变压器厂中使用 ISA-95 应用程序进行调度集成
介绍 在工业批量和连续生产/运营环境中,调度涉及将诸如罐.反应器和其他加工设备之类的资源分配给生产/运营任务.第 4 层生产/运营计划确定要制造什么产品.要制造多少产品以及何时制造.根据设备.物料.人 ...
- day6 斐波那契数列
1.求图片中的表达式: 2.求图中斐波那契数列的值
- Solon Web 开发,七、视图模板与Mvc注解
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- Java读取批量Excel文件
1.首先基础知识: 原文链接:https://blog.csdn.net/baidu_39298625/article/details/105842725 一 :简介 开发中经常会设计到excel的处 ...
- 2月2日 体温APP开发记录
1.阅读构建之法 现代软件工程(第三版) 2.观看Android开发视频教程最新版 Android Studio开发 3.Edit text使用学习
- ansible roles实践——部署zabbix-agent
1.tasks/main.yml 2.template/zabbix_agentd.conf.j2 3.[root@master] /etc/ansible$ vim zabbix_agent.yml