设计一种面向对象脚本语言

简介:

​​​有没有感觉设计一门语言实在是太有意思了,可以自定义语法规则,我的“地盘听我的”。

脚本语言的功能

本书设计一门纯粹的面向对象脚本语言,任何语言都有个名词,这里给这个语言起个名字——sparrow(麻雀)。它支持的功能如下。

1 变量

支持局部变量和局部变量的定义。

变量可引用、赋值。

内部复合数据类型以大写字符开头,如System.print()

2 基本数据类型

数值:包括整数和浮点数。

字符串:包括普通字符和unicode。

list:列表,如Python中的list。

支持字面量创建,如['a', 'b']和new方法创建。

元素通过下标list'[索引]'获得。

map:哈希数组,如Python中的字典。支持字面量创建和new创建。字面量创建如:

{

    'k1':v1
    "k2":v2
}

key可以是任何数据类型。同样支持new方法创建。

value通过下标map'[key]'获得。

range:用以确定一段整数范围,用符号..表示。range包括from和to两个成员,分别表示这段范围的起和始,用区间表示[from, to],即包括from和to。如range“2..6”,2就是from,6就是to,“2..6”表示2、3、4、5、6。“..”类似于Python中的分片操作符“:”,只不过我们包括了结尾的to,而Python不包括,若用区间表示则to后面的是右小括号“)”。

3 运算

数值:+、−、*、/、%。

逻辑:>、<、==、!=、||、&&、?:、|、&等。

位运算:>>、<<。

方法调用:.。

索引:[]。

字符串:+、%(字符串内的表达式)

4 控制结构

支持if-else选择。

支持while循环。

支持for循环。

支持break退出循环。

支持continue,跳过本次循环体后面的部分,继续下一轮循环。

支持return返回。

5 函数

尽管这是一门面向对象语言,但也支持传统意义上的函数,用关键字fun实现函数定义。

函数也是用类实现。

支持函数重载。

6 类

就是传统意义上的class,包括类定义和类实例,静态类。

实现继承,所有类都是object类的子类。

类成员(也称域,或字段)必须先声明再引用。

方法包括method、getter、setter、subscript、subscriptSetter和构造函数。支持块参数,块参数的参数是用“||”括起来的参数列表,以逗号分隔。

支持静态方法。

7 线程

支持线程创建及调度。

8 模块

支持执行模块和模块内模块变量的单独导入。

9 注释

行注释://

块注释:/* 块注释 */

以上列举若有遗漏则以实际代码为主。

关键字

有以下关键字被提前征用了。

var:用于变量定义。

fun:用于函数定义。

if:用于条件判断。

else:用于条件判断的else分支。

true:bool值真。

false:bool值假。

while:用于while循环。

for:用于for循环。

break:用于退出循环。

continue:用于结束本次循环并进入下一轮循环。

return:用于从函数返回。

null:空值。

class:用于类定义。

is:用于判断类是否为某类的子类,即“is a”。

static:用于设置静态文法。

this:用于指向本实例。

super:用于指向父类。

import:用于导入模块。

脚本的执行方式

我们采用传统的虚拟机作为执行方式,即要实现一个虚拟机。编译器先把源码编译为opcode,再让虚拟机执行opcode。

opcode即操作码,是自定义的一套专供虚拟机执行的指令,后面我们在实现虚拟机时会详细介绍。 

“纯手工”的开发环境

既然本着教学的目的我觉得应该拿出教学的诚意,因此这里所说的“纯手工”是指编码中不想借助STL或其他类似的泛型语言,没有第三方库,一切以最基础最原始的形式展现语言的奥秘,因此选择了C语言,确定地说是C89,并不是较新的C99标准,诚意满满,让我们纯手工去编码吧。

基础开发环境是:

宿主系统是Linux,采用CentOS release 6.8 (Final);

编译器是gcc,版本是gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)。

定义sparrow语言的文法

在之前介绍的文法中,我们采用的是大写字母表示非终结符,小写字母表示终结符,然而我们也说过了,在现实中为了便于编程,一般都用正规文法来定义语言,正规文法说白了就是用正则表达式定义的文法,因此本小节的基础是正则表达式,为保证容易看懂,我会用最简单的方式书写正则表达式。

值得注意的是,正规文法与第0章中介绍的文法有很大的差别,主要是涉及终结符是用''表示,原因是正规文法中会涉及()、[]和{},这些在正规文法中都是元字符,有其特殊含义:()表示成为一组,[]表示范围,{}表示重复。

但在实际语言它们只是字符串字面量(即终结符),比如在语言中()表示函数名后面的括号,也可表示表达式中的小括号,[]表示下标索引,因此为避免冲突,正规文法中用单引号括起的是终结符。

其实语法和传统语言差不多,只是用文法来描述就显得生涩了。注意,正规文法中的[]与EBNF中的意义不同,在此表示范围,其中可以用-表示一段连续的范围,比如0-9就表示0至9之间(包括0和9)的任何数;a-z同理,表示字母a到字母z之间的任何字母。[]后面一般会接量词,当然量词不一定只用在[]之后,但它一定是用在某个字符之后以表示该字符的数量,其前不能没有字符。

按照数量级别划分有3种量词,+表示重复出现1次以上,*表示重复出现0次以上,?表示出现0次或1次,比如可用[\t]*表示0个或多个空白字符,其中\t是tab。

注意此处[]中的空白是空格,为了突显这里有个空格就写了两个。.表示任意字符,包括控制字符比如回车等,|表示或者、任意其一,比如a|b,表示a和b两者取其一,注意,|是对两边的整体有效,并不是只对紧邻|的有效。

比如对于ab|cd的意思是ab或者cd,如果想表达abd或acd,可以用分组符号(),就是小括号对儿。()表示作为一组考虑,使相应的正则符号应用于整个组成员。

初次接触文法的读者可能对递归定义感到“消化不良”,比如非终结符exp是用于定义表达式,exp是由infixExp等非终结符组成,而infixExp又是由exp组成,看上去有点死循环出不来了,但你不要忘了,infixExp只是exp的其中一个组成部分,exp还可以由num、id等指代,num和id下面再无递归定义,这就是递归终止的条件。因此infixExp的组成部分exp也会是num或id等。

下面是具体的样本。

以下是上述文件的执行结果,其中的spr是最终的脚本解释器(包括编译器及虚拟机),spr是sparrow的缩写。

以上./spr manager.sp就是执行脚本文件manager.sp,这与任何脚本语言的运行方法都是一致的,执行过就是脚本的输出,大家有兴趣可以核对一下结果,除了System.clock返回的时间戳是动态变化的外,其他不变。

《自制编程语言》

郑钢  著

本书全面从脚本语言和虚拟机介绍开始,讲解了词法分析的实现、一些底层数据结构的实现、符号表及类的结构符号表,常量存储,局部变量,模块变量,方法存储、虚拟机原理、运行时栈实现、编译的实现、语法分析和语法制导自顶向下算符优先构造规则、调试、查看指令流、查看运行时栈、给类添加更多的方法、垃圾回收实现、添加命令行支持命令行接口。

小福利

你认为程序员存在的最大价值是什么,参与话题有机会获奖哦。截止时间9月7日17时,留言+转发本活动到朋友圈,小编将抽奖选出3名读者赠送纸书1本

扫码关注我们

点击阅读原文,直接购买《自制编程语言》

阅读原文​​​​

相关文章
|
3月前
|
PHP
PHP编程中的面向对象和面向过程
【8月更文挑战第28天】在PHP编程中,我们可以选择面向对象或面向过程的编程方式。面向对象的编程方式更符合人类习惯,易于理解,提高程序的重用性,减少代码出错率;而面向过程的编程方式则强调的是功能行为,以具体的功能实现为主。
|
1月前
|
PHP 开发者
PHP编程中的面向对象基础
【9月更文挑战第36天】在PHP的世界中,面向对象编程(OOP)是一块基石。它不仅为代码带来了结构、可维护性与重用性,还让复杂的问题变得简单化。通过掌握类与对象、继承与多态等核心概念,开发者可以构建出更加强大和灵活的应用。本文将引导你理解这些概念,并通过实例展示如何在PHP中应用它们,让你轻松驾驭OOP的力量。
|
1月前
什么叫做 “面向对象” 编程?
本文介绍了面向对象编程(OOP)的概念、核心组件(类和对象)、三大特性(封装、继承和多态)以及六大设计原则,强调了面向对象编程在提高代码的可重用性、模块化、扩展性和维护性方面的优点。
37 1
|
2月前
|
数据库连接 PHP 开发者
PHP编程中面向对象与面向过程的比较
【9月更文挑战第19天】本文旨在探讨PHP编程语言中的两种主要编程范式:面向对象编程(OOP)和面向过程编程。我们将通过对比这两种方法的特点、使用场景及其优缺点,帮助读者更好地理解在PHP开发中如何选择合适的编程模式。文章还将提供一些实际代码示例,以便更直观地展示两种编程方式的差异。
|
3月前
|
PHP 开发者
PHP编程中的面向对象与面向过程
【8月更文挑战第23天】在PHP编程语言中,开发者可以选择使用面向过程或面向对象的方法来编写代码。本文将探讨这两种编程范式的核心概念、优势和局限性,以及如何在实际应用中根据项目需求做出选择。我们将通过比较分析,理解为什么在某些情况下面向对象的编程方式更为合适,而在其他情况下,面向过程的简洁性可能更受青睐。最终,我们将提供一些实用的建议,帮助PHP开发者在面对不同的编程挑战时,能够更加灵活地运用这两种方法。
|
4月前
|
人工智能 Java C#
什么是面向对象的编程语言?
【7月更文挑战第18天】什么是面向对象的编程语言?
75 2
|
3月前
|
PHP 数据库 开发者
PHP编程中的面向对象和面向过程:理解与选择
在PHP的世界里,面向对象和面向过程像是两个老邻居,各有所长,各有所爱。本文将带你走进这两种编程范式的小院,看看它们的日常,聊聊它们的趣事,更重要的是,帮你搞清楚在何时何地该敲响哪位邻居的门。
|
6月前
|
存储 人工智能 运维
面向对象基础
面向对象基础
66 0
面向对象基础
|
开发工具 数据安全/隐私保护 git
面向过程与面向对象及相关工具
面向过程与面向对象及相关工具
|
设计模式 数据安全/隐私保护 C++
基于C++三大特性的图书管理系统【C++面向对象程序设计】
基于C++三大特性的图书管理系统【C++面向对象程序设计】
197 0
基于C++三大特性的图书管理系统【C++面向对象程序设计】