编写Lex和Yacc
大学课程设计中,有一次是编写Lex(词法分析器的生成器)和Yacc(语法分析器的生成器),编写这类工具软件不是一件容易的事情。这篇文章记录了当时编程时候的主要思想,主要还是编译原理的思想。
准备
Lex
根据输入文件生成RE—>NFA—>DFA—>简化的DFA—>根据DFA生成文件。
RE处理:
对正规表达式进行处理使其只有|、*、(、)等特殊符号,代换{}[]-等
将RE转化为后缀表达式
生成NFA:
把下列类型的string转换:
M+----->M.M*
M?------>M|e
最后一共有四种连接:
普通字符(除了.,|,*):

a*:增加三条epsilon边,并且修改终点和起点。

a|b:
新建两个节点,并把其中一个指向原来的两个nfa的起点,另一个被原来的两个终点指向。这四个边均是epsilon。修改终点和起点。

a.b:连接,合并2号和3号节点。(红色代表nfa的起点,黑色代表nfa的终点)

NFA合并:
直接添加一个起点,指向所有nfa的起点。修改起点值,并把原来的终点(每个nfa只有一个)都加入到最后的终点集合。
NFA--->DFA
求闭包
通过epsilon到达的边。迭代直到T’=T,每次
repeat:
T1 = T;
T=T1∪T1所有点能通过epsilon到达的边
until T1==T
求通过某个字母到达的子集
for each(Node* node in d)//对d的每一个节点
{
vector<Node*> eout = node->findNext(c);//求出每个节点的出边集合
d1.insert(eout.begin(), eout.end());//将后继的每一个节点不重复的插入d1
}
最后返回这个d1的闭包
生成DFA
用j标记当前遍历的节点,用p标记已经存在的节点数量
对当前遍历的节点求每个字符的出边集合,如果有的话,就求该集合的闭包,并判断是否已经存在,做相应的处理:
如果已经存在,则加边
如果不存在,新建节点,再加边,p++
DFA最小化
参考维基百科中关于Hopcroft的算法。
但是对于DFA来说,刚开始并不能简单地分为两个非终结符和终结符的集合,因为每个终结符最后应该在单独的一个集合中。
Yacc
读取文件设置符号和产生式的值—>计算FIRST和FOLLOW—>构造LR(1)预测分析器和PPT(预测分析表)—>LR(1)—>LALR—>打印到输出文件。
计算FIRST和FOLLOW
还是参考的“现代编译原理”这本书。
对于LR(1)可以不计算FOLLOW,所以只计算FIRST。
初始化:每个终结符的FIRST是自己
设置一个是否修改的bool变量,检测本次循环是否修改过
遍历每个产生式
每个产生式的右部符号,如果当前符号前面都是可为空,则将这个产生式左部的FIRST增加当前符号。
如果每个符号都是可为空的,则把这个产生式置为可为空。
构造预测分析器(FA)和预测分析表(PPT)
计算闭包和计算GOTO
类似Lex的计算闭包和子集
构造LR状态图和分析表
类似构造DFA
反思
感觉这次做的比较辛苦,可能这是因为是工具软件的原因吧。工具软件要能针对不同的输入,生成不同的代码,然后生成出来的代码可以去分析一个文件。
编写Lex和Yacc的更多相关文章
- Lex和Yacc入门
Lex和Yacc入门 标签: lexyacc 2013-07-21 23:02 584人阅读 评论(0) 收藏 举报 分类: Linux(132) 原文地址:http://coanor.blog ...
- lex与yacc快速入门
lex与yacc快速入门 [原创] 声明:原创文章,转载注明出处http://www.cnblogs.com/lucasysfeng/ 联系作者:lucasysfeng@gmail.com 第一节.l ...
- 正则语言引擎:一个简单LEX和YACC结合运用的实例
本文先描述了LEX与YACC的书写方法.然后利用LEX与YACC编写了一个简单正则语言的引擎(暂时不支持闭包与或运算),生成的中间语言为C语言. 正则引擎应直接生成NFA或DFA模拟器的输入文件,但在 ...
- Lex与Yacc学习(一)之环境配置篇
Abstract 在开发程序的过程中经常会遇到文本解析的问题,例如:解析 C 语言源程序,编写 脚本引擎等等,解决这种文本解析的方法有很多,一种方法就是自己手动用 C 或者 C++直接编写解析程序,这 ...
- Windows下lex 与 yacc的使用(2)
Windows下lex 与 yacc的使用 ...
- Windows下lex 与 yacc的使用
Windows下lex 与 yacc的使用 首先 下载下载flex和bison.网址是http://pan.baidu.com/s/1dDlfiW5 选择下载就好了,下载后解压到你电脑中的任一盘中. ...
- lex 和 yacc 的区别与联系
lex负责词法解析,而yacc负责语法解析,其实说白了就是lex负责根据指定的正则表达式,将输入的字符串匹配成一个一个的token,同时允许用户将当前匹配到的字符串进行处理,并且允许返回一个标识当前t ...
- Lex与Yacc学习(十)之Yacc库
Yacc库 每个实现都需要有用的例程库,在UNIX系统中,可以通过cc命令行尾端给出-ly标志(或通过其他系统下的等价物)来包含库. 库的内容在不同的实现之间是不同的,但总是包括main()和yyer ...
- Lex与Yacc学习(九)之Yacc语法
Yacc语法 本文讨论yacc语法的格式并描述可用的各种特征和选项 yacc语法结构 yacc语法包括三部分:定义段.规则段和用户子例程段 ...定义段... %% ...规则段... %% ...用 ...
随机推荐
- Intellij Idea 13 vmoptions (Mac版本)
-ea -server -Xms1g -Xmx1g -Xss16m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DoEscapeAnalysis -XX:+ ...
- CentOS 6.5下搭建NFS文件服务器
环境介绍:服务器: 192.168.0.1客户机: 192.168.0.2安装软件包:服务器和客户机都要安装nfs 和 rpcbind 软件包:yum -y install nfs-utils rpc ...
- index full scan/index fast full scan/index range scan
**************************1************************************* 索引状态: valid. N/A . ...
- 设置tabbar的角标与第三方库Masonry的基本使用
// 设置tabbar的角标 [[[[[self tabBarController] viewControllers] objectAtIndex: 0] tabBarItem] setBadgeVa ...
- VB热点答疑(2016.5.11更新Q4、Q5)
收录助教君在VB习题课上最常被问到的问题,每周更新,希望对大家有所帮助. Q1.如何让新的文本内容接在原来的内容后面/下一行显示? A1.例如,Label1.text原本的内容是"VB程序设 ...
- OpenCart本地调试环境搭建
OpenCart简介: 免费开源网络版电子商务系统,是建立在线商务网站首选之一.有众多用户和开发基础,结合其丰富特性与模板插件,可最大化定制在线商店.(也就是用来方便开网店的) 本地调试准备: Fir ...
- JavaMail API 1.4.7邮件发送
下载oracle javaMail API: http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive- ...
- SGU 162.Pyramids
时间限制:0.25s 空间限制:6M; 题意: 按照AB, AC, AD, BC, BD, CD.给出一个空间四面体的6条边长.求出它的体积. Solution: 欧拉四面体公式: ...
- 在easyui dialog的子页面内如何关闭弹窗
因项目需要在dialog中添加滚动条,所以就在div中加了iframe: <div id="applyRefundDialog" style="display:no ...
- js 表达式与运算符 详解(下)
比较运算符: > .>= .<. <=. ==. !=. ===. !==. 比较运算符的结果都为布尔值 ==只比较值是否相等 而 ===比较的是值和数据类型都要 ...