![](https://img-blog.csdnimg.cn/20201014180756926.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
编译原理
数学家是我理想
博客:https://wmathor.com
展开
-
正规式到最小化DFA
整体的步骤是三步:一、先把正规式转换为NFA(非确定有穷自动机)二、在把NFA通过“子集构造法”转化为DFA三、在把DFA通过“分割法”进行最小化一、正规式转换为NFA第一步很简单,就是反复运用下图的规则:给出一个例题,来自Google book。本文主要根据这个例题来讲二、子集构造法NFA转换为DFA——子集构造法三、DFA最小化Hopcroft算法...原创 2018-10-30 12:58:01 · 4001 阅读 · 0 评论 -
《两周自制脚本语言》——第五天(设计语法分析器)
笔记、源码同步在github上,欢迎Star,蟹蟹~### 写在前面本章会用到一个Parser类,该类已经写好,直接先导入即可,在Code/Stone文件夹里面### Stone语言的语法首先,我们借助BNF来试写一下Stone语言的语法规则。具体内容请参见代码清单5.1。规则中出现的NUMBER、IDENTIFIER、STRING、OP与EOL都是终结符,分别表示整型字面量、标识符、字...原创 2019-09-29 07:42:18 · 1069 阅读 · 0 评论 -
《两周自制脚本语言》——第六天(通过解释器执行程序)
笔记、源码同步在github上,欢迎Star,蟹蟹~只要通过语法分析得到抽象语法树,剩下的就简单了,只要从根结点开始遍历至叶节点,并计算各节点的内容即可,这就是解释器的基本实现原理eval方法与环境对象要根据得到的抽象语法树来执行程序,各个语法树节点对象的类都需要具备eval方法。eval是evaluate(求值)的缩写。eval方法将计算与以该节点为根的子树对应的语句、表达式及子表达式,...原创 2019-09-29 07:42:51 · 517 阅读 · 0 评论 -
《两周自制脚本语言》——第七天(添加函数功能)
笔记、源码同步在github上,欢迎Star,蟹蟹~本章将为Stone语言添加函数功能。此外,除了基本的函数定义与调用执行,本章还会引入名为闭包(closure)的语法功能,使Stone语言可以将变量赋值为函数,或将函数作为参数传递给其他函数扩充语法规则首先将函数定义语句称为def语句。def语句仅能用于最外层代码。也就是说,用户无法在代码块中定义函数例如,下面的代码定义了函数fact...原创 2019-09-29 07:43:23 · 532 阅读 · 0 评论 -
《两周自制脚本语言》——第八天(关联Java语言)
笔记、源码同步在github上,欢迎Star,蟹蟹~我们还没有为Stone语言实现类似于Java语言中system.out.print1n的函数,因此程序还无法输出字符串显示。本章将继续扩展Stone语言,使它能够在程序中调用Java语言中的static方法原生函数Java语言提供了名为原生方法的功能,用于调用C语言等其他一些语言写成的函数。我们将为Stone语言添加类似的功能,让他能够调...原创 2019-09-29 07:43:56 · 305 阅读 · 0 评论 -
《两周自制脚本语言》——第九天(设计面向对象语言)
笔记、源码同步在github上,欢迎Star,蟹蟹~今天我们为Stone语言添加类与对象的支持### 设计用于操作类与对象的语法再添加的类与对象的处理功能后,下面的Stone语言就能被正确执行了```class Position { x = y = 0 def move(nx,ny) { x = nx; y = ny }}p = Positi...原创 2019-09-29 07:44:31 · 403 阅读 · 0 评论 -
《两周自制脚本语言》——第十天(无法割舍的数组)
笔记、源码同步在github上,欢迎Star,蟹蟹~数组(array)是几乎所有程序设计语言都会提供的一种基本的语法功能。本章将为Stone语言增加对数组的支持。与Java语言的数组相同,Stone语言的数组长度无法中途修改扩展语法分析器如果Stone语言支持数组,就能写出下面这样的程序a = [2,3,4]print a[1]a[1] = "three"print "a[1]: ...原创 2019-09-29 07:45:00 · 338 阅读 · 0 评论 -
《两周自制脚本语言》——第十一天(优化变量读写性能)
笔记、源码同步在github上,欢迎Star,蟹蟹~优化语言处理器性能的手段多种多样,多数手段的核心思想都在于提前计算好能够计算的值通过简单数组实现环境之前我们通过环境(Environment对象)来管理变量名与变量值的对应关系。哈希表的算法复杂度为O(1),是一种性能优秀的数据结构,无论表中含有多少元素,它都能在固定时间内完成查找操作。不过,哈希表的查找速度依然不算非常迅速。对于现在的S...原创 2019-09-29 07:45:36 · 403 阅读 · 0 评论 -
《两周自制脚本语言》——第十二天(优化对象操作性能)
笔记、源码同步在github上,欢迎Star,蟹蟹~### 减少内存占用第9天的实现使用了环境来表现Stone语言中的对象。环境中不仅含有由字段名与相应的值组成的键值对,还记录了由方法名与Function对象组成的键值对。这种实现的内存利用率很低JavaScript每个对象都能拥有不同方法的语言,这种实现方式较为合适。然而,Stone语言中同一个类的对象只能具有相同的方法。因此,语言处理器...原创 2019-09-29 07:46:19 · 584 阅读 · 0 评论 -
《两周自制脚本语言》——第十三天(设计中间代码解释器)
笔记、源码同步在github上,欢迎Star,蟹蟹~在使用中间代码解释器时,我们要事先将抽象语法树转换为中间代码。简单来说,中间代码是一种虚拟的机器语言,因此,中间代码的转换方法,其实与编译器将抽象语法树转换为真正的机器语言时采用的方法大体相同中间代码与机器语言之间利用抽象语法树,语言处理器需要在节点之间往返操作,这是一件费时的工作。因此,如果语言处理器能够实现计算遍历顺序,并以此重新排列...原创 2019-09-29 07:47:22 · 1252 阅读 · 0 评论 -
《两周自制脚本语言》——第四天(用于程序表示的对象)
笔记、源码同步在github上,欢迎 Star,蟹蟹~语言处理器在词法分析阶段将程序分割为单词后,将开始构造抽象语法树。抽象语法树(AST,Abstract Syntax Tree)是一种用于表示程序结构的树形结构。语法分析的主要任务是分析单词之间的关系,如判断哪些单词属于同一个表达式或语句,以及处理左右括号(单词)的配对等问题。这一阶段还会检查程序中是否含有语法错误。### 抽象语法树的定...原创 2019-09-29 07:41:37 · 618 阅读 · 0 评论 -
《两周自制脚本语言》——第三天(分割单词)
笔记、源码同步在github上,欢迎Star,蟹蟹~语言处理器的第一个组成部分是词法分析器(lexer)。程序的源代码最初只是一长串字符串,这样的字符串很难处理,语言处理器通常会首先将字符串中的字符以单词为单位分组,切割成多个子字符串。这就是词法分析### Token对象下面是某个程序中的一行代码```while i < 10 {```词法分析会把它拆分为下面这样的字符串`...原创 2019-09-28 11:02:15 · 749 阅读 · 1 评论 -
词法分析——DFA 的最小化:Hopcroft 算法
通过前面对于词法自动生成部分的学习,我们已经掌握了如何从源码生成到 DFA那么为什么要对 DFA 进行最小化处理呢?下面给出一个例子:如下是我们之前写出的 a(b|c)* 的 NFA:它可以对应转换成如下的 DFA:在上面的 DFA 中非接受状态和接受状态是不能够合并的,因为如果合并,就会接受一个ϵ\epsilonϵ串,这是明显不正确的。但是如果同样是接受状态或者同样是非接受状态的话...原创 2018-10-30 12:58:43 · 6050 阅读 · 0 评论 -
词法分析——NFA 转换成 DFA: 子集构造算法
因为 NFA 的状态转移不确定,不适合直接做词法分析器的识别,在写算法时往往需要使用回溯。所以我们一般使用子集构造算法,将 NFA 转换成 DFA,得到确定的状态转移,再转化成一个词法分析器的代码。下面给出一个关于 NFA 到 DFA 转化的例子,我们使用 a(b|c)* 做例:对于ϵ\epsilonϵ的边表示一种零代价的转换,n1n_1n1可以在没有任何输入操作的情况下直接滑动到n2n...原创 2018-10-30 12:59:16 · 4847 阅读 · 0 评论 -
词法分析——有限状态自动机(FA)
举个例子在上图中,Σ\SigmaΣ表示自动机可以识别的所有的不同的字符的集合。Σ=a,b\Sigma = {a,b}Σ=a,bS 是状态集,在这里只有三种状态,所以 S = {0, 1, 2}q0q_0q0是初始状态,我们一般约定只有一个单向箭头的边指向的节点是起始状态。q0q_0q0 = 0F 是终结状态,或者说是接收状态,在图中表示为双圈。 F = {2}{(q0,a)−&...原创 2018-10-30 13:00:07 · 4396 阅读 · 0 评论 -
词法分析——上下文无关文法和推导
上下文无关文法是描述程序语言语法的强有力的数学工具乔姆斯基文法体系3型文法:正则文法:词法结构2型文法:上下文无关文法:语法结构1型文法:上下文有关文法0型文法:任意文法每一个外部文法(大圈)都比内部文法(小圈)表达能力强举个自然语言处理的例子自然语言中的句子的典型结构主语 谓语 宾语名词 动词 名词例子:名词:{羊, 老虎, 草, 水}动词:{吃, 喝}...原创 2018-10-30 13:00:28 · 16236 阅读 · 4 评论 -
词法分析——正则表达式(RE)
正则表达式对给定的字符集Σ=C1,C2,...,Cn\Sigma = C_1,C_2,...,C_nΣ=C1,C2,...,Cn空串ϵ\epsilonϵ是正则表达式对于任意c∈Σc\in\Sigmac∈Σ,ccc是正则表达式如果M和N是正则表达式,则以下也是正则表达式:选择: M | N = {M, N}连接: MN = {mn | m ∈ M, n ∈ N}闭包: M* ...原创 2018-10-30 13:00:49 · 870 阅读 · 0 评论 -
chomsky文法分类
chomsky文法分类0123型乔姆斯基把文法法分成四种类型,即0型、1型、2型和3型。这几种文法类型的概念一定要掌握,是一个非常重要的考点0型文法设G=(VN,VT,P,S)G=(V_N,V_T,P,S)G=(VN,VT,P,S),如果它的每个产生式α→β是这样一种结构:α∈(VNV_NVN∪VTV_TVT)*且至少含有一个非终结符,而 β∈(VNV_NVN∪VTV_TVT)*...原创 2018-10-30 13:01:44 · 5801 阅读 · 0 评论 -
词法分析——词法分析的任务
在编译原理介绍中,我们已经对前端的工作有了大致的了解词法分析器的任务是读入源程序,对其进行一定的切分,得到记号流对于字符流和记号流之间的区别,下面给出一个例子来说明if (x > 5) y = "hello";else z = 1;对面上面这段程序,在词法分析器的眼中,是这样表示的:i, f, " ", (, x, " ",>, " ", 5, ), \...原创 2018-10-30 13:02:25 · 6197 阅读 · 0 评论 -
《两周自制脚本语言》——第一天(来,我们一起做些什么吧)
笔记、源码同步在github上,欢迎Star,蟹蟹~### 机器语言与汇编语言有些程序设计语言无需借助软件执行,这些语言称为机器语言。机器语言可以由硬件直接解释执行,理论上不必使用软件机器语言写成的程序本质上是一个位数很长的二进制数字。由于它不易阅读,人们通过汇编语言程序来表述这个巨大的数字。因此,如果要执行汇编语言写成的程序,用户通常需要使用软件将其转换为机器语言,这种软件称为汇编程序(...原创 2019-09-28 11:01:11 · 760 阅读 · 0 评论 -
《两周自制脚本语言》——第二天(程序设计语言)
笔记、源码同步在github上,欢迎 Star,蟹蟹~### 麻雀虽小、五脏俱全的程序设计语言Stone语言应该具备哪些语法功能呢?四则运算必不可少,还有字符串处理以及对变量提供支持。if、while语句等一些基本的控制语句也必需。Stone语言姑且算是一种脚本语言,因此不需要制定静态数据类型,用户在使用时也不必事先声明变量。只是这样一来,如果程序中出现字符串变量相加减的语句,就会引起运行错...原创 2019-09-28 11:01:44 · 950 阅读 · 0 评论 -
《两周自制脚本语言》——第十四天(让Stone语言支持静态类型以优化性能)
笔记、源码同步在github上,欢迎Star,蟹蟹~前一天我们借助Java语言设计了一种专用的虚拟机,用于执行中间代码。从内部来看,该虚拟机通过Java语言的Object类型来表示所有类型的值,整数也将由Integer对象表现。不可否认,这是程序执行速度较慢的一个重要原因今天我们将利用静态数据类型,尽可能以int类型的值来表示整数值。同时,我们将不再使用专用的虚拟机,而直接使用Java虚拟机...原创 2019-09-30 09:11:44 · 791 阅读 · 0 评论