可配置语法分析器开发纪事(三点五) 生成下推自动机的具体步骤

刚刚发了上一篇文章之后就发现状态机画错了。虽然LiveWriter有打开博客并修改文章的功能,不过为了让我留下一个教训,我还是决定发一篇勘误。这个教训就是,作分析的时候不要随便“跳步”,该一步一步来就一步一步来。其实人呢,就是很容易忘掉以前的教训的了。第一个告诉我不能这么干的人其实是小学三年级的数学老师。当时我因为懒得写字,所以计算应用题的时候省了几步,被批评了。

故事就从状态机开始。文法我就不重复了,见上一篇文章。现在我们从状态机开始。第一个状态机是直接从文法变过来的:

开发纪事(三点五) 生成下推自动机的具体步骤-可配置交换显卡没有了">

然后我们把所有的非终结符跳转都通过Shift和Reduce连接到该非终结符所代表的状态机的状态上面,就会变成下面的图。具体的做法是,对于每一条非终结符的跳转,譬如说S0 –> Symbol –> S1。首先抹掉这条跳转。然后增加两条边,分别是S0到Symbol的起始节点,操作是Shift<S0>。还有从Symbol的终结节点到S0,操作是Pop<S0> Reduce。Shift<S>等于把状态S给push到堆栈里,然后Pop<S>等于在状态里面弹出内容是S的栈顶元素。如果失败了怎么办呢?那就不能用这条跳转。跟上图一样,所有输入$跳转到Finish的边,操作都是要Pop<Null>的。在刚开始分析的时候,堆栈有一个Null值,用来代表“语法分析从这里开始”。

这个图的粗虚边代表所有跟左递归有关的跳转。这些边是成对的,分别是左递归跳转的Shift和Reduce。如果不是为了实现高性能的语法分析的话,其实这个状态机已经足够了。这个图跟语法分析的“状态跳转轨迹”有很大的关系。虽然IDList0你不知道第一步要跳转到IDList0还是ID0,不过没关系,现在我们先假设我们可以通过某种神秘的方法来预测到。那么,当输入是A,B,C$的时候,状态跳转轨迹就会是如下的样子:

时间: 2024-08-04 01:46:06

可配置语法分析器开发纪事(三点五) 生成下推自动机的具体步骤的相关文章

可配置语法分析器开发纪事(一) 构造语法树

就像之前的博客文章所说的,(主要还是)因为GacUI的原因,我决定开发一个更好的可配置轻量级语法分析器来代替之前的落后的版本.在说这个文章之前,我还是想在此向大家推荐一本<编程语言实现模式>,这的确是一本好书,让我相见恨晚. 其实说到开发语法分析器,我从2007年就已经开始在思考类似的问题了.当时C++还处于用的不太熟练的时候,难免会做出一些傻逼的事情,不过总的来说当年的idea还是能用的.从那时候开始,我为了锻炼自己,一直在实现各种不同的语言.所以给自己开发一个可配置语法分析器也是在所难免的

可配置语法分析器开发纪事(二) 构造符号表

上一篇博客讲到了构造语法树的问题.有朋友在留言问我,为什么一定要让语法分析器产生语法树,而不是让用户自己决定要怎么办呢?在这里我先解答这个问题. 1.大部分情况下都是真的需要有语法树 2.如果要直接返回计算结果之类的事情的话,只需要写一个visitor运行一下语法树就好了,除去自动生成的代码以外(反正这不用人写,不计入代价),代码量基本上没什么区别 3.加入语法树可以让文法本身描述起来更简单,如果要让程序员把文法单独放在一边,然后自己写完整的语义函数来让他生成语法树的话,会让大部分情况(需要语法

可配置语法分析器开发纪事(三) 生成下推自动机

上一篇博客讲到了构造符号表的事情.构造完符号表之后,就要进入语义分析的后一个阶段了:构造状态机.跟我以前写的如何实现正则表达式引擎的两篇文章讲的一样,自动机先从Epsilon Nondeterministic Automaton开始,然后一步一步构造成Deterministic Automaton.但是语法分析和正则表达式有很大不同,那么这个自动机是什么样子的呢? (对学术感兴趣的人可以去wiki一下"下推自动机") 下推自动机和有限自动机的区别是,下推自动机扩展成普通的自动机的时候,

可配置语法分析器开发纪事(五) 构造一个真正能用的状态机(中)

上一篇博客写到了如何给一个非终结符的文法规则构造出一个压缩过的下推状态机,那么今天说的就是如何把所有的文法都连接起来.其实主要的idea在(三)和他的勘误(三点五)里面已经说得差不多了.但是今天我们要处理的是带信息的transition,所以还有一些地方要注意. 所以在这里我们先把几条文法的最后的状态机都列出来(大图): 开发纪事(五) 构造一个真正能用的状态机(中)-语法树构造"> 本栏目更多精彩内容:http://www.bianceng.cn/Programming/cplus/

可配置语法分析器开发纪事(六) 构造一个真正能用的状态机(下)

上一篇文章对大部分文法都构造出了一个使用的状态机了,这次主要来讲右递归的情况.右递归不像左递归那么麻烦,因为大部分右递归写成循环也不会过分的让语法树变得难以操作,不过仍然有少数情况是我们仍然希望保留递归的语法树形状,譬如C++的连等操作,因此这里就来讲一下这个问题. 右递归是怎么形成的呢?在这里我们先不想这个问题,我们来看一个普通的文法.在上一篇文章我们已经说过了,如果一条文法有一个非终结符引用了另一条文法,那么就要做一条shift和reduce来从这个状态机穿插到那个状态机上: 开发纪事(六)

可配置语法分析器开发纪事(四) 构造一个真正能用的状态机(上)

本来说这一篇文章要把构造确定性状态机和look ahead讲完的,当我真正要写的时候发现东西太多,只好分成两篇了.上一篇文章说道一个基本的状态机是如何构造出来的,但是根据第一篇文章的说法,这一次设计的文法是为了直接构造出语法树服务的,所以必然在执行状态机的时候就要获得构造语法树的一切信息.如果自己开发过类似的东西就会知道,类似LALR这种东西,你可以很容易的把整个字符串分析完判断他是不是属于这个LALR状态机描述的这个集合,但是你却不能拿到语法分析所走的路径,也就是说你很难直接拿到那颗分析树.没

Windows 8风格应用开发入门 三十五 触控输入

Windows 8设备通常具有多点触摸屏,用户可以同时使用多个手指来进行不同的输入交互,如点击. 拖动或收缩等手势操作.另外Windows 8中将触摸.鼠标和笔/触笔交互是作为指针输入进行接收.处理 和管理. 一.手势处理 首先我们来汇总一下Windows 8中常用的手势都有哪些. 开发入门 三十五 触控输入-windows10触控板手势"> 1,点击:用一个手指触摸屏幕,然后抬起手指. 2,长按:用一个手指触摸屏幕并保持不动 . 3,滑动:用一个或多个手指触摸屏幕并向着同一方向移动. 4

Lucene.Net 2.3.1开发介绍 —— 三、索引(三)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(三) 3.Field配置所产生的效果  索引数据,简单的代码,只要两个方法就搞定了,而在索引过程中用到的一些类里最简单,作用也不小的就是Field,接下来看看Field的各项设置都会有什么样的效果. 代码 3.1   Code 1/**//// <summary> 2/// 索引数据 3/// </summary> 4private void Index() 5{ 6    Analyzer analyzer = ne

求教:Eclipse如何为新语言配置语法高亮?

问题描述 一个很小众的编程语言,想尝试用Eclipse作为IDE,有关键词若干,希望实现语法高亮和代码提示.请问该如何配置?小弟新手上路,请予指教,烦请讲详细一点.谢谢先 解决方案 解决方案二:eclipse语法提示(红色波浪线)如何开启关闭设置步骤:windows-->perferences-->editors-->texteditor-->annotation在里面选择errors,把其中的三个选项都勾上就可以啦代码提示按alt+/实现语法高亮是系统自带的,不用设置解决方案三: