Chinaunix首页 | 论坛 | 博客
  • 博客访问: 773578
  • 博文数量: 111
  • 博客积分: 3895
  • 博客等级: 中校
  • 技术积分: 1300
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-29 21:26
文章分类

全部博文(111)

文章存档

2014年(22)

2013年(8)

2010年(14)

2009年(21)

2008年(46)

我的朋友

分类: LINUX

2013-09-28 22:59:11

lex-yacc


 在开源世界里,lex与yacc的对应实现是:flex与bison。在fedora下,可以通过如下命令进行安装:
  sudo yum -y install flex bison

Lex的本质,是利用正则表达式和额外实现的语法规则(如start condition),来描述token的切分方法,即词法规则。lex把用户定制的token切分方法,实现为一个yylex函数(此函数通常为int yylex(),但也有其他形式)。 yylex函数的作用,是从输入的文件流(从stdin读取)中,每次切分出一个token,然后返回。每个token都含有两个属性: token-type和token-value。token-type就是yylex的返回值,是整型;而token-value的数据类型,由宏 YYSTYPE决定,值需赋值给yylval(其类型即为YYSTYPE)。YYSTYPE,可以由用户显式定义,也可以利用yacc生成(可以通过在 yacc的语法规则文件里,定义%union的结构,yacc就会把这个结构作为宏YYSTYPE的定义)。lex孤立来看没有意义的,因为它只生成一个 yylex函数。这个函数,只有被yacc所用,才真正发挥实效。

Yacc的本质,是利用BNF(Backus Naur Form, 巴科期范式),来描述语法规则, 然后根据这些规则生成语法解析的C代码。关于词法规则与语法规则的区别,个人理解为,词法规则描述token的切分方法(如何划分token,token 的类别是什么,其值是又是什么),语法规则描述token之间的组合方式(哪种token组合是合法的,当遇到某种组合时,执行什么动作)。显然yacc 的处理,必须建立在token已经被划分出来的基础之上。而yacc划分token的方法,依赖于由用户定义的一个yylex函数。而lex就是为了方便 实现这个函数而设计的。当然,这个函数,也可由我们自已手动编写,lex不是必须的,只是它提供了一个更快且通用的实现方法而已。

Yacc 为什么要求yylex切分出来的token具有两个属性(token-type, token-value)?yacc的语法规则,包含三个元素: Nonterminal token, Terminal token。 Terminal token,是不可再分的,例如关键字、数值、标识符等。Nonterminal token是可以再分解的,即它是由Terminal tokne组合而成的,这个组合的方式,就是通过语法规则来描述的。本质上,把语法规则全部扩展之后,每个元素都是Terminal token。而为了描述这些Terminal token的组合方式,只能用这些token的类别(token-type)而不是值(token-value)来抽象它们。所以,当然yacc对一个文 本流进行解析时,是通过把这些文本流的token的type取出来,然后用语法规则去匹配,如果匹配成功,则表明语法合格,否则会报一个错(通过 yyerror(char *s)函数,这个函数也由用户实现)。
阅读(606) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

luozhenwu2013-09-28 23:01:39

Yacc 与 Lex 快速入门
http://www.ibm.com/developerworks/cn/linux/sdk/lex/