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快速入门之安全策 ...
随机推荐
- Html.Partial和Html. RenderPartial用法
Html.Partial和Html. RenderPartial用法 Html.partial和RenderPartial的用法与区别Html.partial和RenderPartial都是输出htm ...
- jQuery的三种bind/One/Live/On事件绑定使用方法
本篇文章介绍了,关于jQuery新的事件绑定机制on()的使用技巧.需要的朋友参考下 今天浏览jQuery的deprecated列表,发现live()和die()在里面了,赶紧看了一下,发现从jQ ...
- Java经典23创意模式设计模式(两)
本文介绍5其余两种创意模式:模型构建器(Builder).原型模型(PROTOTYPE). 一.建造者模式(别名:生成者模式) 将复杂对象的构建和它的表示分离,使得相同的构建过程能够创建不同的表示. ...
- [CLR via C#]1.5 本地代码生成器:NGen.exe
原文:[CLR via C#]1.5 本地代码生成器:NGen.exe 1. NGen.exe工具,可以在一个程序安装到用户计算机时,将IL代码编译成为本地代码.由于代码在安装时已经编译好,所以CLR ...
- Spring该讲座
看看今天Spring. 国内搞Java开发的朋友们.对Spring一定不会陌生. Spring的历史? 谈起Spring.就会想起Ejb2.0.虽然.现实中有非常多基于Ejb2.0的成功系统,可是Ej ...
- 动画云创始人胥克谦&课程格子创始人李天放分享创业经历
原文地址:http://student.csdn.net/mcd/topic/163587/955044 2014年10月18日在北京科技大学成功举办了CSDN高校俱乐部全国巡讲,现场參会学生有一百余 ...
- Java-继承特性
继承的特点: 1.提高了代码的复用性. 2.让类与类之间发生了关系,有了这个关系,才有了多态的特性. (注意:千万不要为了获取其他类的功能,简化代码而继承:必须是类与类之间有所属关系才可以继承,所属关 ...
- 接口自动化测试:Thrift框架RPC协议客户端开发
import java.lang.Thread.State;import java.util.Iterator;import java.util.List; import org.apache.thr ...
- C++ AMP 介绍(两)
C++ AMP 介绍(两) 最后更新:2014-05-02 读前提:<C++ AMP介绍(一个)> 周边环境:Windows 8.1 64bit英文版,Visual Studio 2013 ...
- 快速构建Windows 8风格应用7-页面视图概览
原文:快速构建Windows 8风格应用7-页面视图概览 本篇博文主要介绍Windows 8风格应用中包含哪些视图.Visual Studio 2012和模拟器中如何开发和调试不同的页面视图.页面视图 ...