导读

我在之前的

杨韬是我的知识星球“码农翻身”的一个大学生,他在星球提到做了一个简单的编程语言解释器,我建议他把过程给写出来, 就是这篇文章了。

下文的“我”就是杨韬。

为什么要自己写一个解释器?

从大学开始学习编程, 现在已经快两年了, 接触了不少的编程语言。最开始入门学了C语言; 后来想写安卓

但是仔细想想我似乎又什么也没有学到,过年回家的时候, 遇到一个对计算机很感兴趣的四年级的小朋友(ps: 小朋友会写一点点

我都不好意思说自己是学计算机的了, 居然连这些基础的问题都没有搞清楚。 这是促使我去深入学习

学习编译原理最简单的方法(对我来说)大概是自己实现一门编程语言, 虽然费时费力, 不过能对整个过程有个清晰的了解。

另外一个重要原因是有一种想要自己写一门语言的冲动。 尤其是在学了这么多门语言之后就会萌生出这样的念头。不同的语言有不同的让我喜欢的特性: Python有漂亮简洁的语法, 静态语言Go实现了像动态语言一样的鸭子类型的接口, Dart有很多语法糖和方便的异步… (当然这些特性是仁者见仁, 智者见智的)。

但是又不能找到一门语言,具备所有自己喜欢的特性, 那就自己写一个好了,可以把自己喜欢的特性都加上。

学习的过程

学校的编译原理的课程安排在了大三, 我还没有学过, 所以一切都是从0开始。 我先看了前桥和弥写的《自制编程语言》一书, 这本书的实战性很强, 没有介绍太多的理论知识, 而是直接教你怎么写编程语言。

我从这本书中了解了写一门编程语言的大致过程和大致的思路。 不过书中的很多解释不够充分, 对于完全没有接触过编译技术的人来说还是有点费解(也可能是我自己理解能力不够好)。

我也是在自己了解了大致思路后就开始自己尝试写, 然后再回过头来看书, 看作者提供的源代码, 才能比较好地了解作者是在干嘛。

还有一些书中内容介绍的不够充分, 比如yacc和lex的使用。 这种工具毕竟比较流行, 网上找找别人写的

因为更喜欢在实战中学习, 所以前期只是了解了大致思路没有特别深入的学习理论知识, 就直接开始码代码了。 在具体实现的过程中遇到问题, 再去看书或是网上寻找答案。

设计和实现

我选择写一个动态语言的解释器, 而不是静态语言的编译器。

之所以要写解释器, 不是因为我更偏好动态语言, 其实相比而言我更喜欢静态语言。 真正的原因是, 我觉得这只是第一次尝试, 很多东西都不会, 肯定会写得很烂的,不如先就写动态语言, 等真正学得比较好了, 再回过头来写一门自己喜欢的语言。

正式开始写代码前, 我还要给这门语言取个名字,虽然只是个练手的项目, 不过还是得有个名字吧。 取名字还正不是一件容易得事, 就像给函数或者类取一个恰如其分的名字一样。

听说恰当的函数名或类名还能反应整个项目的设计是否合理, 逻辑清晰, 语言的名字似乎并没有这样的意义。

我脑袋里闪过的第一个名字是Cactus(仙人球, 仙人掌)。 我觉得很喜欢这个名字, 就把Cactus暂时留个我要写的静态语言了(

前面提到了lex和yacc, 我在自己写的编程语言里面也使用了这两个工具做词法分析和语法分析。 既然是自己要写一门语言为什么还要用别的工具呢? 当然不能以”不重复造轮子”作为借口, 我就是为了造轮子才想要自己写编程语言的, 真正的目的是为了简单。

前面提到我把这当作一个练手的项目, 为了熟悉整个过程, 我把简单作为了整个过程的一个原则,很多地方我可以想到更优但更加复杂的实现方式, 但是大多数仍然采用了最简单最能保持整个项目逻辑清晰的实现方式。 我更多的目的是为了了解整体过程, 整体结构, 所以局部就尽量保持简单了吧(当然比较懒也是重要原因)。

当然后续词法分析和语法分析肯定会自己实现一下, 毕竟这算是编译器或者解释器的前端, 也很重要的。

解释器是用C语言写的。 之前从来没有用C语言写过这么大的项目(虽然到目前一共也就2千多行的代码), 这次也让我学会了很多C语言的高级用法。 比如 :

vo

是一个返回值为空,

void (*signal(int signo,void(*func)(int)))(int);

是一个返回值为函数指针, 参数为(int signo,void(*func)(int)), (一个int, 一个函数指针)的函数, 其中函数名为signal。

之所以用函数指针, 是为了用C语言写面向对象, 最开始我完全是使用面向过程, 只是简单的通过不同文件实现简单的封装。

后来越写越大, 就出现各种问题, 比如头文件交叉引用引起编译器报错。 还有很多地方用面向对象可以更好地实现, 比如要处理表达式的创建和求值, 如果能有一个表达式的接口, 就能利用多态的好处, 不需要再写一个巨大的switch, case语句, 使用枚举来判断不同的表达式, 调用不同的函数。

我听说限制

多态也可以通过自己实现虚函数表, 在

还有一些问题是关于这门语言本身的设计问题:

(1) for, if这类的语句中变量的作用域问题

一开始我设计的是Java, C++一样的, for, if的代码块中声明的变量, 它作用域只存在于整个代码块中。 后来想到了这是一门弱类型的动态语言, 独立的运行环境也没什么特别的用处, 于是就改成了和Python一样: 这种代码块都没有独立的运行环境。

(2) 把函数看成什么的问题。

比如Java这种纯粹面向对象的语言, 函数只能是对象的方法。 我这里是把函数作为一种基础数据类型, 像字符串一样, 可以直接用于传参, 赋值。

毕竟这是自己的编程语言,可以把它设计成自己喜欢的样子, 所以大多数的设计都是根据自己的想法, 自己觉得怎么合理就怎么来(当然不是天马行空地胡乱设计, 而是根据自己地实际经验选择合理的设计吧)。

当然最开始写一门编程语言的时候,有很多地方不知道怎么设计才合理, 这个时候我就参考自己学过的编程语言, 想想它为什么要采用这种设计, 出于怎样的考虑。

这样的思考, 让我对之前学过的编程语言有有了更加深刻的认识, 可以说是受益匪浅吧。 我渐渐地也认识到编程语言的设计很多时候都是设计者编程思维的体现。

简单地介绍一下Hedgehog

说了这么多, 是时候简单地介绍一下我写的这门编程语言了。目前还很简陋, 后面再慢慢地完善它吧。

hedgehog 的多数设计和 python 比较相似, 无需声明变量类型, if,for等语句没有块级作用域。

语法上又有点像 go 语言: if, for后面不需要(), 但是后面的代码块都必须加{};

没有while, 不过有for condition {}来替代。 不过行尾必须加;这点和 go 不同。

大多数设计都是为了简化实现方式, 比如必须加{}, ;是为了简化语法的

数据类型

a = 10;  //int

b = 3.14;//float

c = true;//boolean

d = null;//null

s = "Hello, World!";//string

控制语句

a = 10;

if a > 10 { // `()` is not necessary.

b = a+20;

} elsif a==10 {

b = a+10;

} else {

b = a-10;

}

print(b);

循环

for i=0; i<10; i=i+1 {

print(i);

if i>=4 {break;}

}

i = 0;

for i<10 {

if i<5 {continue;}

print(i);

}

函数

function也被看作一种值(基本数据类型), 不过目前还没有对它实现

// 模仿python首页的函数

func fbi(n) {

a, b = 0, 1;

for a

print(a);

a, b = b, a+b;//支持这种赋值方式

}

}

fbi(100);

func factorial(n) {

if n==0 {return 1;}

return n*factorial(n-1);

}

print(factorial(5));

目前只实现了一个原生函数print。 print接收一个基本数据类型作为参数, 输出并换行, 或者无参数, 直接换行。

运算符

大多数与c保持一致, 除了&, |。 因为没有提供位运算的功能, 所以直接用这两个符号表示逻辑与和逻辑或。

b = 2;

a = 10;

if a>20 & b<10 {

print("`b` is less than 10 and `a` is greater than 20");

}

if a>20 | b<10 {

print("`b` is less than 10 or `a` is greater than 20");

}

“What I cannot create, I do not understand。” 我喜欢这种从自己制作过程中学习的方式。 这种方式给了我一种踏实感, 让我觉得自己是真地明白了整个过程,而不是仅仅记住了什么公式, 学会了调用新的

【本文为51

戳这里,看该作者更多好文

初中生学python还是java_当你在纠结学Python还是Java时,大二学生已经开始造编程语言了!...相关推荐

  1. python实习做什么工作-大一/大二学生Python实习的困惑?

    题主是一名非名校的CS本科学生,现在遇到了一些困惑,想请教一下热心的segmentfault网友.因为不是985/211名校,现在题主所在的这所学校我感觉学风非常不好,第一是整体水平太低,一学期结束了 ...

  2. 一个大二学生送给大一学弟学妹的建议

    博主简介:先简单的介绍一下我吧,本人是一名大二学生,来自四川.目前所学专业是人工智能,致力于在CSDN平台分享自己的学习内容. 我为什么要写这篇文章? 我来到CSDN也已经一年了,在这一年里面,我学会 ...

  3. 大二学车,一个无比愚蠢的选择

    二十多年前,我刚上大学,就有老师教导:未来社会的三大技能是计算机.外语.驾驶.我现在从事着计算机专业的教学,在为着计算机相关专业的学生好好学习计算机做着无限的努力:我爱人从事着大学英语的教学,她的无奈 ...

  4. 人工智能用python还是java_人工智能选择python还是java语言

    最近几年伴随着大数据的发展,人工智能也迎来了前所未有的发展契机,大量的专业人才涌向了人工智能领域,相信未来人工智能领域会进一步赢得市场的追捧. 不少打算学计算机的学生,想从事人工智能行业,但是对于人工 ...

  5. python计算机二级操作题_计算机二级Python考试心得分享体会总结

    前言: 我叫夏某鸣,德州学院,大二学生,在学习python之前,学习过c语言,数据结构,做过嵌入式开发,有一点功底,但是不多,通过学习不同的语言的编程也锻炼了一些思维,但涉猎面还是不广,也不怎么精通, ...

  6. 答大二软件工程专业学生——重点学什么

    [留言] 贺老师你好,我是软件工程专业的大二学生,我们学校这个学期的专业学习不是很多,已经学完了.参考学校的培养计划,下个学期开始,差不多都是专业课的学习.数据库原理,算法设计,计算机组成原理,操作系 ...

  7. 零基础编程学python还是java_零基础学python还是java 二者有哪些区别

    对于初学者来说,python相对比较简单.python的语法类似于伪代码或普通英语,不需要严格的代码结构,入门简单. 零基础适合python还是java 从语言本身来说,python是出了名的简洁.p ...

  8. 逼自己玩命学了3个多月,吃透了Python技术核心!分享给你,让你今年进个大厂!...

    魔幻的2020年,疫情下就业大受影响,很多岗位缩招,而数据分析相关工作岗位(如数据分析师.数据挖掘师等岗位)却在增加.非专业数据分析岗位(如运营.市场.销售等岗位)也要求"数据分析" ...

  9. 2020职场AI技能排行榜:TensorFlow热度飙升,Python最火,市场部也在学

    本文转自: 机器之心 还有一个月就是 2020 年了.近日,在线教育网站 Udemy 根据其学员的课程数据,制作了一份<2020 年职场学习趋势报告>,指出了哪些技能最受职场人关注.报告指 ...

  10. Python要了解哪些编程基础 如何学Python比较好

    Python要了解哪些编程基础?如何学Python比较好?不管怎么说,Python都是大家进军IT行业值得选择的语言.毕竟它不但使用,而且还好用.更值得一提的是,它非常容易入门.而且在人工智能.传统编 ...

最新文章

  1. 解析jsonarra_使用JSONReader或JSONObject / JSONArray解析JSON数据
  2. textarea 换行_textarea自动换行方法总结
  3. python中*args和**args的不同
  4. 1033. 旧键盘打字(20)
  5. ai驱动数据安全治理_AI驱动的Web数据收集解决方案的新起点
  6. 【POJ - 2195】Going Home(二分图最优匹配,费用流 或 KM)
  7. python执行语句转换成str_python3.x,_python3.4.3如何转换str字符串?,python3.x - phpStudy...
  8. 你真的了解iOS怎么取属性的吗?
  9. HTML+CSS+JS实现React简单的计算器实例
  10. 2008年小结,我想,我就从这里开始
  11. mysql返回的数据是什么格式_磁盘格式化后能恢复数据吗?先了解什么是格式化...
  12. Atitit.java 反编译 工具  attilax 总结
  13. 域名没备案使用七牛cdn加速
  14. (翻译)从底层了解ASP.NET体系结构 [转]
  15. 命令行工具解析Crash文件,dSYM文件进行符号化
  16. playsound报错
  17. syn 攻击脚本 python_python制作SYN泛洪攻击工具
  18. wim工具扫描linux磁盘,[V1.30.2011.501版]WimTool -- Wim文件的图形视窗处理工具[无忧首发]...
  19. 【使用心得】ChatGPT做出行攻略
  20. 并发读源码——并发读源码Striped64/LongAdder/DoubleAdder/LongAccumulator/DoubleAccumulator

热门文章

  1. 移动端自动化测试实战(一)
  2. CONTINUOUS CONTROL WITH DEEP REINFORCEMENT LEARNING
  3. 云打码的简单使用举例
  4. 微x模块怎么导入主题_WESHOP | 基于微服务的小程序商城系统
  5. Mac 苹果电脑创建一个新的管理员账号
  6. 2022年的国外广告联盟,合格的EMU者有你吗?
  7. 从0到1构建基于Springboot+SpringCloud的微信点餐系统
  8. mysql基本语句大全6_mysql基本sql语句大全(基础用语篇)
  9. 淘宝商品历史价格接口/商品历史价走势接口对接代码分享
  10. Oracle、mysql产品性能优化总结