lex与yacc快速入门
lex与yacc快速入门 【原创】
声明:原创文章,转载注明出处http://www.cnblogs.com/lucasysfeng/
第一节、lex和yacc是什么?
lex 代表 lexical analyzar(词法分析器),yacc 代表 yet another compiler compiler(编译器代码生成器)。lex和yacc在UNIX下分别叫flex和bison. 可以搜索到很多介绍flex&bison的文章,但这类文章对初学者来说不太容易看懂。
我们举个简单的例子来理解lex和yacc:在linux下,有很多系统配置文件,一些linux下的软件也有配置文件,那么程序是如何读取配置文件中的信息的呢?先用到lex词法分析器,读取配置文件中的关键词(后面说到的token标记其实可看做关键词);然后把关键词递交给yacc,yacc对一些关键词进行匹配,看是否符合一定的语法逻辑,如果符合就进行相应动作。
上面举的例子是分析配置文件内容的,当然可分析其他文件内容,或者制作编译器等。
第二节、一个简单的lex程序。
1、程序代码。
来看一个简单的lex程序,代码见下面,这段lex程序的目的是:输入几行字符串,输出行数,单词数和字符的个数。
1 |
/******************************************* |
程序中yytext是lex变量,匹配模式的文本存储在这一变量中。yylex()这一函数开始分析,它由lex自动生成。关于lex变量和函数后续再介绍,这里只是通过简单的lex程序来认识lex.
2、按照下面过程编译运行。
#flex test.l
#gcc lex.yy.c –lfl
#./a.out
然后输入一段文字,按ctrl+d结束输入,则会输出行数,单词数和字符的个数。
见下图:
3、分析上面的lex程序。
(1)%%把文件分为3段,第一段是c和lex的全局声明,第二段是规则段,第三段是c代码。
(2)第一段的c代码要用%{和%}括起来,第三段的c代码不用。
(3)第二段规则段,[a-zA-Z]+ \n . 是正则表达式,{}内的是c编写的动作。
4、编译时不加-lfl选项。
上面编译时用gcc lex.yy.c –lfl,那么如何直接用gcc lex.yy.c进行编译呢?答案是加上yywrap函数(具体原因见lex的库和函数分析),代码如下。
1 |
/******************************************* |
第三节、lex进阶。
修改第二节程序,将正则表达式放在全局声明中,使逻辑更清晰。
1 |
/******************************************* |
编译运行同第二节。
第四节、lex再进阶—循环扫描。
下面给出一个lex程序,这个程序在扫描到 + 或 - 时做一个特殊输出。当调用yylex()函数时,若扫描到return对应的标记时,yylex返回,且值就为return后的值;若没扫描到return对应的标记,yylex继续执行,不返回。下次调用自动从前一次的扫描位置处开始。
1 |
/******************************************* |
编译和运行见下图:
第五节、yacc语法。
1、yacc语法规则部分和BNF类同,先来看BNF巴克斯范式。
(1)<> 内包含的内容为必选项;
(2)[] 内的包含的内容为可选项;
(3){ } 内包含的为可重复0至无数次的项;
(4) | 表示在其左右两边任选一项,相当于"OR"的意思;
(5)::= 是“被定义为”的意思;
(6)双引号“”内的内容代表这些字符本身;而double _quote用来表示双引号。
(7)BNF范式举例,下面的例子用来定义java中的for语句:
FOR_STATEMENT ::=
"for" "(" ( variable_declaration |
( expression ";" ) | ";" )
[ expression ] ";"
[ expression ]
")" statement
2、yacc语法。
注:components是根据规则放在一起的终端和非终端符号,后面是{}括起来的执行的动作。
3、语法例子。
1 |
param : NAME EQ NAME { |
yacc文件第一段中定义的token,lex文件对目标进行扫描并返回这些token。yacc文件对规则冒号右边componets进行匹配,如果符合一定语法规则就执行相应动作。
1 |
simple_sentence: subject verb object |
分析:|表示左右两边任选一项,如| subject verb object prep_phrase ;中|的左边为空,所以该句表示匹配空或者subject verb object prep_phrase ;而上面还有一句subject verb object ,所以
simple_sentence: subject verb object
| subject verb object prep_phrase ;
的意思是匹配subject verb object 或 subject verb object prep_phrase ;
第六节、lex和yacc结合使用。
1、lex程序。
当匹配a b c not时分别返回相应的token.
1 |
/******************************************* |
2、yacc程序。
当扫描到A_STATE B_STATE时打印1,当扫描到
A_STATE B_STATE
c_state_not_token时打印2,当扫描到NOT时打印3.
其中,
A_STATE B_STATE NOT是token,
c_state_not_token
是非终端符号,此处定义为
c_state_not_token : C_STATE {}.
1 |
/******************************************* |
3、编译和运行。
lex和yacc在UNIX下分别叫flex和bison.
第七节、lex和yacc结合使用进阶。
1、我们希望用lex和yacc结合完成下面文件解析。
我们对文本test.txt进行分析,test.txt中的内容如下:
ZhangSan=23
LiSi=34
WangWu=43
扫描test.txt文本后,我们希望输出:
ZhangSan is 23 years old!!!
LiSi is 34 years old!!!
WangWu is 43 years old!!!
2、利用lex扫描test.txt文本,返回token.
1 |
/******************************************* |
3、yacc根据lex返回的token,判断这些token是否符合一定的语法,符合则进行相应动作。
1 |
/******************************************* |
4、编译运行。
补充:lex变量和和函数。
lex与yacc快速入门的更多相关文章
- Yacc 与 Lex 快速入门
Yacc 与 Lex 快速入门 Lex 与 Yacc 介绍 Lex 和 Yacc 是 UNIX 两个非常重要的.功能强大的工具.事实上,如果你熟练掌握 Lex 和 Yacc 的话,它们的强大功能使创建 ...
- Yacc 与 Lex 快速入门(词法分析和语法分析)
我们知道,高级语言,一般的如c,Java等是不能直接运行的,它们需要经过编译成机器认识的语言.即编译器的工作. 编译器工作流程:词法分析.语法分析.语义分析.IR(中间代码,intermediate ...
- Lex和Yacc入门
Lex和Yacc入门 标签: lexyacc 2013-07-21 23:02 584人阅读 评论(0) 收藏 举报 分类: Linux(132) 原文地址:http://coanor.blog ...
- Go 快速入门
入门 Go 语言需要多久?答案是 -- 读完这篇文章的时间!不妨找一个周末的下午,踏上 Go 之旅吧! 更新记录: 2016.12.12: 完成重制 2016.11.02: 增加重点理解和参考链接 2 ...
- Web Api 入门实战 (快速入门+工具使用+不依赖IIS)
平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html 屁话我也就不多说了,什么简介的也省了,直接简单概括+demo ...
- SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)
SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/si ...
- 前端开发小白必学技能—非关系数据库又像关系数据库的MongoDB快速入门命令(2)
今天给大家道个歉,没有及时更新MongoDB快速入门的下篇,最近有点小忙,在此向博友们致歉.下面我将简单地说一下mongdb的一些基本命令以及我们日常开发过程中的一些问题.mongodb可以为我们提供 ...
- 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...
- 【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...
随机推荐
- C#将image中的显示的图片转换成二进制
原文:C#将image中的显示的图片转换成二进制 1.将Image图像文件存入到数据库中 我们知道数据库里的Image类型的数据是"二进制数据",因此必须将图像文件转换成字节数组才 ...
- 十天学Linux内核之第七天---电源开和关时都发生了什么
原文:十天学Linux内核之第七天---电源开和关时都发生了什么 说实话感觉自己快写不下去了,其一是有些勉强跟不上来,其二是感觉自己越写越差,刚开始可能是新鲜感以及很多读者的鼓励,现在就是想快点完成自 ...
- Hadoop-1.1.2、HBase-0.94.7完全分布式集群结构
爱的技术可以应用到实际生活生产,做艺术向往的东西不腻和音乐. 现将前期手里面的一个项目做一个大致的总结,与大家一起分享.交流.进步. 项目如今正在线上执行,项目名--基于Hadoop的数据分析综合管理 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(7)-DBSession的封装
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(7)-DBSession的封装 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 ...
- ACM 入门计划
acm 本文由swellspirit贡献 ACM • I can accept failure. but I can't accept not trying. Life is often compar ...
- 都能看懂的嵌入式linux/android alsa_aplay alsa_amixer命令行使用方法
前几天在嵌入式linux上用到alsa command,网上查的资料多不给力,仅仅有动手一点点查,最终能够用了,将这个用法告诉大家,以免大家少走弯路. 0.先查看系统支持哪几个alsa cmd: ll ...
- JBPM——MyEclipse开发环境的搭建
第一次接触JBPM我不知道如何在工程中的应用.查了一些资料.大约在JBPM随着时代的发展有一定的了解.首先JBPM它是JBoss件平台的一个组成部分.是一个灵活的,易扩展的工作流管理系统,仅仅只是这个 ...
- css+html简单的布局demo
于html介绍css作风.可以改变html块状布局,局更加美观.接下来看一个基础布局的小样例: <html> <head> <meta http-equiv=" ...
- hibernate 一对多关联关系(具体分析)
在领域模型中, 类与类之间最普遍的关系就是关联关系. 在 UML 中, 关联是有方向的. 以 Customer 和 Order 为例: 一个用户能发出多个订单, 而一个订单仅仅能属于一个客户. 从 ...
- 【Java编码准则】の #12不要使用不安全或者强度弱的加密算法
安全性要求高的应用程序必须避免使用不安全的或者强度弱的加密算法,现代计算机的计算能力使得攻击者通过暴力破解能够攻破强度弱的算法.比如,数据加密标准算法DES是极度不安全的,使用类似EFF(Electr ...