• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > 90分钟实现一门编程语言(极简解释器教程)

90分钟实现一门编程语言(极简解释器教程)

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了极简,极简风格,极简生活,极简安全助手,极简安全助手官方下载等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文介绍了如何使用 C# 实现一个简化 Scheme——iScheme 及其解释器。

如果你对下面的内容感兴趣:

  • 实现基本的词法分析,语法分析并生成抽象语法树。
  • 实现嵌套作用域和函数调用。
  • 解释器的基本原理。
  • 以及一些 C# 编程技巧。

那么请继续阅读。

如果你对以下内容感兴趣:

  • 高级的词法/语法分析技术。
  • 类型推导/分析。
  • 目标代码优化。

本文则过于初级,你可以跳过本文,但欢迎指出本文的错误 :-)

代码样例

public static int Add(int a, int b) {
  return a + b;
}
>> Add(3, 4)
>> 7
>> Add(5, 5)
>> 10
</div>

这段代码定义了 Add 函数,接下来的 >> 符号表示对 Add(3, 4) 进行求值,再下一行的 >> 7 表示上一行的求值结果,不同的求值用换行分开。可以把这里的 >> 理解成控制台提示符(即Terminal中的PS)。

什么是解释器

解释器图示

解释器(Interpreter)是一种程序,能够读入程序并直接输出结果,如上图。相对于编译器(Compiler),解释器并不会生成目标机器代码,而是直接运行源程序,简单来说:

解释器是运行程序的程序。

计算器就是一个典型的解释器,我们把数学公式(源程序)给它,它通过运行它内部的”解释器”给我们答案。

CASIO 计算器

iScheme 编程语言

iScheme 是什么?

  • Scheme 语言的一个极简子集。
  • 虽然小,但变量,算术|比较|逻辑运算,列表,函数和递归这些编程语言元素一应俱全。
  • 非常非常慢——可以说它只是为演示本文的概念而存在。

OK,那么 Scheme 是什么?

  • 一种函数式程序设计语言。
  • 一种 Lisp 方言。
  • 麻省理工学院程序设计入门课程使用的语言(参见 MIT 6.001 和 计算机程序的构造与解释)。

计算机程序的构造与解释

使用 波兰表达式(Polish Notation)。
更多的介绍参见 [Scheme编程语言]。
以计算阶乘为例:

C#版阶乘

public static int Factorial(int n) {
  if (n == 1) {
    return 1;
  } else {
    return n * Factorial(n - 1);
  }
}
</div>

iScheme版阶乘

(def factorial (lambda (n) (
  if (= n 1)
    1
    (* n (factorial (- n 1))))))
</div>

数值类型

由于 iScheme 只是一个用于演示的语言,所以目前只提供对整数的支持。iScheme 使用 C# 的 Int64 类型作为其内部的数值表示方法。

定义变量

iScheme使用`def`关键字定义变量

>> (def a 3)
>> 3
>> a
>> 3
</div>

算术|逻辑|比较操作

与常见的编程语言(C#, Java, C++, C)不同,Scheme 使用 波兰表达式,即前缀表示法。例如:

C#中的算术|逻辑|比较操作

// Arithmetic ops
a + b * c
a / (b + c + d)
// Logical ops
(cond1 && cond2) || cond3
// Comparing ops
a == b
1 < a && a < 3
</div>

对应的iScheme代码

; Arithmetic ops
(+ a (* b c))
(/ a (+ b c d))
; Logical ops
(or (and cond1 cond2) cond3)
; Comparing ops
(= a b)
(< 1 a 3)
</div>

需要注意的几点:

iScheme 中的操作符可以接受不止两个参数——这在一定程度上控制了括号的数量。
iScheme 逻辑操作使用 and , or 和 not 代替了常见的 && , || 和 ! ——这在一定程度上增强了程序的可读性。
顺序语句

iScheme使用 begin 关键字标识顺序语句,并以最后一条语句的值作为返回结果。以求两个数的平均值为例:

C#的顺序语句

int a = 3;
int b = 5;
int c = (a + b) / 2;
</div>

iScheme的顺序语句

(def c (begin
  (def a 3)
  (def b 5)
  (/ (+ a b) 2)))
</div>

控制流操作

iScheme 中的控制流操作只包含 if 。

if语句示例

>> (define a (if (> 3 2) 1 2))
>> 1
>> a
>> 1
</div>

列表类型

iScheme 使用 list 关键字定义列表,并提供 first 关键字获取列表的第一个元素;提供 rest 关键字获取列表除第一个元素外的元素。

iScheme的列表示例

>> (define alist (list 1 2 3 4))
>> (list 1 2 3 4)
>> (first alist)
>> 1
>> (rest alist)
>> (2 3 4)
</div>

定义函数

iScheme 使用 func 关键字定义函数:

iScheme的函数定义

(def square (func (x) (* x x)))
(def sum_square (func (a b) (+ (square a) (square b))))
</div>

对应的C#代码

public static int Square (int x) {
  return x * x;
}
public static int SumSquare(int a, int b) {
  return Square(a) + Square(b);
}
</div>

递归

由于 iScheme 中没有 for 或 while 这种命令式语言(Imperative Programming Language)的循环结构,递归成了重复操作的唯一选择。

以计算最大公约数为例:

iScheme计算最大公约数

(def gcd (func (a b)
  (if (= b 0)
    a
    (func (b (% a b))))))
</div>

对应的C#代码

public static int GCD (int a, int b) {
  if (b == 0) {
    return a;
  } else {
    return GCD(b, a % b);
  }
}
</div>

高阶函数

和 Scheme 一样,函数在 iScheme 中是头等对象,这意味着:

  • 可以定义一个变量为函数。
  • 函数可以接受一个函数作为参数。
  • 函数返回一个函数。

iScheme 的高阶函数示例

; Defines a multiply function.
(def mul (func (a b) (* a b)))
; Defines a list map function.
(def map (func (f alist)
  (if (empty? alist)
    (list )
    (append (list (f (first alist))) (map f (rest alist)))
    )))
; Doubles a list using map and mul.
>> (map (mul 2) (list 1 2 3))
>> (list 2 4 6)
</div>

小结

对 iScheme 的介绍就到这里——事实上这就是 iScheme 的所有元素,会不会太简单了? -_-

接下来进入正题——从头开始构造 iScheme 的解释程序。

解释器构造
iScheme 解释器主要分为两部分,解析(Parse)和求值(Evaluation):

 1、解析(Parse):解析源程序,并生成解释器可以理解的中间(Intermediate)结构。这部分包含词法分析,语法分析,语义分析,生成语法树。
2、求值(Evaluation):执行解析阶段得到的中介结构然后得到运行结果。这部分包含作用域,类型系统设计和语法树遍历。
词法分析

词法分析负责把源程序解析成一个个词法单元(Lex),以便之后的处理。

iScheme 的词法分析极其简单——由于 iScheme 的词法元素只包含括号,空白,数字和变量名,因此C#自带的 String#Split 就足够。

iScheme的词法分析及测试

pu



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 90分钟实现一门编程语言(极简解释器教程)

相关文章

  • 2017-05-28winform中的ListBox和ComboBox绑定数据用法实例
  • 2017-05-28C#用ComboBox控件实现省与市的联动效果的方法
  • 2017-05-28C#中DataTable排序、检索、合并等操作实例
  • 2017-05-28C#中的匿名方法实例解析
  • 2017-05-28一看就懂:图解C#中的值类型、引用类型、栈、堆、ref、out
  • 2017-05-28C#使用ping命令的两个例子
  • 2017-05-28C#实现子窗体与父窗体通信方法实例总结
  • 2017-05-28C#实现的字符串转MD5码函数实例
  • 2017-05-28C#实现托盘程序并禁止多个应用实例运行的方法
  • 2017-05-28C#检测DataSet是否为空的方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#多线程传递参数及任务用法示例
    • C#中类与结构的区别实例分析
    • C#中事件的继承实例分析
    • C#自定义类型强制转换实例分析
    • C#中Forms.Timer、Timers.Timer、Threading.Timer的用法分析
    • C#中的DataSet、string、DataTable、对象转换成Json的实现代码
    • C# 手动/自动保存图片的实例代码
    • C# WORD操作实现代码
    • C#中验证sql语句是否正确(不执行语句)
    • C# 函数覆盖总结学习(推荐)

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有