从0到1打造一门属于自己的编程语言(一)

前言

学习编程语言的开发,目的不是为了造轮子,而是为了了解程序语言的本质和原理,方便我们日常的开发

学习此课程前需要提前掌握以下知识:

  • 了解汇编语言
  • 熟悉至少一门高级编程语言

编程语言的来源

我们如果想要和外国人交流,那么我们必须学会外语, 或者让外国人学咱们的语言

我们如果想要指挥计算机,那么我们必须学会计算机语言,让计算机学咱们的语言不太可能,至少现在不行!

很多人都认为我们平常使用的编程语言比如C语言 Java语言等就是计算机语言,这种说法不太严谨, 因为计算机压根不认识编程语言,它只认识二进制码, 也就是说 二进制码才是计算机真正的语言

那我们要指挥计算机岂不是得学二进制码(机器码),在编程语言发明之前,确实是如此

科技的进步来源于懒惰

人类势必不会甘愿长期忍受机器码的摧残, 为了摆脱效率低下的编码,于是乎,聪明的人类发明了编程语言,比如汇编, 相比机器码汇编显然要舒服的多, 但是随着时间的推移,人们发现汇编语言存在非常严重的弊端, 最突出的一点就是不同cpu架构需要制定一套不同指令集,通俗一点就是不同cpu对应着不同的一套汇编语言,这就导致了无法跨平台

有人会问,为什么当时大家不使用同一种cpu呢, 历史不能预知未来的发展,每个时代都有各自的商业竞争

新技术的出现往往是因为问题的长期累积

于是乎,跨平台语言C语言问世了, 但是C语言知识语言跨平台,但是其编写的程序并不跨平台

于是乎,可以程序跨平台的Java语言问世了

……..

从这段历史,我们不难发现:

编程语言只是一个方便人类与计算机交流的工具

只是工具,仅此而已

我们现在花大量时间和精力所学所用的都是别人制作出来的工具

当我们因熟练掌握几门编程语言而洋洋得意时,是否有想过,我们只是一个工具的熟练运用者

我并不是说学语言很low, 毕竟编程语言的门槛也不低,需要花大量时间和精力才能有效掌握,我只是想说,一旦你明白了语言的创造过程, 那就等于你掌握了现在市面上所有的编程语言, 所有的语言,原理都是一样的,只不过语法和关键字不同,仅此而已

也就是说,我们需要去了解工具的生产过程

思考

如果你去网上搜相关编程语言制作的视频或资料, 基本上都是词法分析,语法分析,语义分析等等, 让人一头雾水, 直接劝退

试想一下,在若干年前编程语言还没有问世的时候,有词法语法语义符号token等等这一些个含义么? 完全没有!

这些理论都是前人经验总结而成, 经验固然很好,能少走弯路,但是对于初学者来讲极其不友好

只有从初学者的角度出发,才能更平滑地学习到原本复杂的知识

因此抛开这些专业术语吧,从0开始出发

起步

假如现在编程语言还未问世,你现在要自创一门语言方便人类开发, 你会怎么做?

比如我想让计算机帮忙算个数,计算1+1

原本使用机器码可能得这样写:

1
4F 9B 55 7C 2D 3A  ;实际过程中我们一般使用十六进制进行表示,cpu执行的时候执行的是对应的二进制

此时,我可能会考虑用一句话来代替这个计算1加1的功能,比如

1
加:1+1   ;这是不是好理解多了

问题来了, 如果将我这句话转成机器码呢? 也就是说,我们需要将这句话翻译成机器码, 那怎么翻译呢? 是不是得需要一个翻译工具呀

于是乎,我们与此同时需要想办法整一个翻译工具, 由于我设计的这句话是敲在计算机上的,而不是写在纸上的, 如果是写在纸上的,兴许我们可以造一台机器将我写的内容转印成机器码,然后机器码敲入计算机:cry:… 这种愚蠢的做法, 简直就是科技的倒退

既然是直接敲在计算机中,那我们的翻译工具必然也是一个能被cpu执行的程序, 那我们需要先编写翻译工具这个程序的机器码

理论上是这么个逻辑

我们需要一边指定语法规则,一边编写和优化的翻译程序,因为我们的需求不单单是让计算机做加法运算

这个能把我们指定的语言翻译成机器码的翻译工具,就是当今所说的编译器,后文皆以编译器替代

编译器该如何写

由于源代码都是存放在文件中,按照我们的正常思维,最先想到的是将这个文件中的内容读取出来,然后从头到尾进行匹配判断,根据不同的关键字判断不同的功能,然后用与之对应的机器码进行替换

cpu在进行文件读取的时候,本质上读取的是二进制,那我们编写的中文或者英文和二进制数据的一一对应关系就涉及到编码格式问题,常见的编码格式有:

  • ASCII码 (只识别英文)
  • GBK (识别英文和中文)
  • UTF-8 (识别各个国家的语言)

假如我们接下来要使用UTF-8进行编码,那么我们需要指定一张表,也就是二进制码和功能之间的一一对应关系,比如算术运算中这个关键字:编译器从文本中连续读取两个字节二进制数据然后查表,如果对应上了加法功能,那么继续往后读取需要进行运算的内容,读到结束标记的时候,然后将之前所读取的二进制转化成与之对应功能的机器码,以此类推,这个结束标记也是由我们来定,我们可以使用分号、回车换行或者其它特殊的符号作为一行语句的结束

本文为作者原创 转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

0%